1. Introduction

This report documents the data preparation and processing steps for the “Anxiety Support App: Marketing Audience Identification” case study. The primary objective is to identify and characterize potential target audiences for the “Calm Button” application.

2. Project Setup and Data Acquisition

2.1 Loading Necessary Libraries

(Libraries are loaded in the setup chunk)

2.2 Defining Project Paths

(Paths are defined in the setup chunk)

2.3 Importing the Dataset

if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Importing Data ---\n\n")
}


--- Importing Data ---
anxiety_data_raw <- read_csv(data_file_path)
Rows: 12000 Columns: 20── Column specification ───────────────────────────────────────
Delimiter: ","
chr  (7): Gender, Occupation, Smoking, Family History of An...
dbl (13): ID, Age, Sleep Hours, Physical Activity (hrs/week...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
if (capture_all_output) {
  print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:06 CST"

3. Detailed Data Inspection (Prepare Phase)

3.1 Import check

if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Import Check ---\n\n")
}


--- Import Check ---
head(anxiety_data_raw)

if (capture_all_output) {
  print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:06 CST"

3.2 Column Name Cleaning

if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Column Name Cleaning ---\n\n")
}


--- Column Name Cleaning ---
anxiety_data_clean_names <- janitor::clean_names(anxiety_data_raw)

if (capture_all_output) {
    print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:06 CST"

3.3 Data Structure

if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Data Structure ---\n\n")
}


--- Data Structure ---
str(anxiety_data_clean_names)
spc_tbl_ [12,000 × 20] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ id                             : num [1:12000] 1 2 3 4 5 6 7 8 9 10 ...
 $ age                            : num [1:12000] 56 46 32 60 25 38 56 36 40 28 ...
 $ gender                         : chr [1:12000] "Female" "Male" "Female" "Male" ...
 $ occupation                     : chr [1:12000] "Other" "Teacher" "Doctor" "Doctor" ...
 $ sleep_hours                    : num [1:12000] 9.6 6.4 6.9 9.2 9.2 6.7 3.8 4.9 6.2 8.3 ...
 $ physical_activity_hrs_week     : num [1:12000] 8.3 7.3 1 3.7 2.5 9.9 7.5 0.5 9 9.3 ...
 $ caffeine_intake_mg_day         : num [1:12000] 175 97 467 471 364 194 411 413 284 148 ...
 $ alcohol_consumption_drinks_week: num [1:12000] 6 6 14 16 2 16 13 4 6 18 ...
 $ smoking                        : chr [1:12000] "No" "No" "No" "No" ...
 $ family_history_of_anxiety      : chr [1:12000] "No" "No" "No" "Yes" ...
 $ stress_level_1_10              : num [1:12000] 4 3 2 6 7 2 2 3 4 5 ...
 $ heart_rate_bpm_during_attack   : num [1:12000] 145 143 60 94 152 174 81 88 121 145 ...
 $ breathing_rate_breaths_min     : num [1:12000] 33 18 34 19 15 25 22 36 28 12 ...
 $ sweating_level_1_5             : num [1:12000] 3 5 1 1 4 3 4 5 2 4 ...
 $ dizziness                      : chr [1:12000] "No" "Yes" "No" "No" ...
 $ medication                     : chr [1:12000] "No" "No" "No" "Yes" ...
 $ therapy_sessions_per_month     : num [1:12000] 4 0 7 4 0 2 5 6 0 3 ...
 $ recent_major_life_event        : chr [1:12000] "Yes" "No" "Yes" "Yes" ...
 $ diet_quality_1_10              : num [1:12000] 9 9 10 5 1 1 10 4 5 10 ...
 $ severity_of_anxiety_attack_1_10: num [1:12000] 10 8 5 8 1 8 10 2 4 4 ...
 - attr(*, "spec")=
  .. cols(
  ..   ID = col_double(),
  ..   Age = col_double(),
  ..   Gender = col_character(),
  ..   Occupation = col_character(),
  ..   `Sleep Hours` = col_double(),
  ..   `Physical Activity (hrs/week)` = col_double(),
  ..   `Caffeine Intake (mg/day)` = col_double(),
  ..   `Alcohol Consumption (drinks/week)` = col_double(),
  ..   Smoking = col_character(),
  ..   `Family History of Anxiety` = col_character(),
  ..   `Stress Level (1-10)` = col_double(),
  ..   `Heart Rate (bpm during attack)` = col_double(),
  ..   `Breathing Rate (breaths/min)` = col_double(),
  ..   `Sweating Level (1-5)` = col_double(),
  ..   Dizziness = col_character(),
  ..   Medication = col_character(),
  ..   `Therapy Sessions (per month)` = col_double(),
  ..   `Recent Major Life Event` = col_character(),
  ..   `Diet Quality (1-10)` = col_double(),
  ..   `Severity of Anxiety Attack (1-10)` = col_double()
  .. )
 - attr(*, "problems")=<externalptr> 
if (capture_all_output) {
    print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:06 CST"

3.4 Data Distribution

if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Data Summary ---\n\n")
}


--- Data Summary ---
summary(anxiety_data_clean_names)
       id             age           gender         
 Min.   :    1   Min.   :18.00   Length:12000      
 1st Qu.: 3001   1st Qu.:29.00   Class :character  
 Median : 6000   Median :41.00   Mode  :character  
 Mean   : 6000   Mean   :40.97                     
 3rd Qu.: 9000   3rd Qu.:53.00                     
 Max.   :12000   Max.   :64.00                     
  occupation         sleep_hours    
 Length:12000       Min.   : 3.000  
 Class :character   1st Qu.: 4.800  
 Mode  :character   Median : 6.500  
                    Mean   : 6.483  
                    3rd Qu.: 8.200  
                    Max.   :10.000  
 physical_activity_hrs_week caffeine_intake_mg_day
 Min.   : 0.000             Min.   :  0.0         
 1st Qu.: 2.500             1st Qu.:122.0         
 Median : 5.000             Median :244.0         
 Mean   : 5.031             Mean   :246.7         
 3rd Qu.: 7.525             3rd Qu.:371.0         
 Max.   :10.000             Max.   :499.0         
 alcohol_consumption_drinks_week   smoking         
 Min.   : 0.000                  Length:12000      
 1st Qu.: 5.000                  Class :character  
 Median : 9.000                  Mode  :character  
 Mean   : 9.493                                    
 3rd Qu.:15.000                                    
 Max.   :19.000                                    
 family_history_of_anxiety stress_level_1_10
 Length:12000              Min.   : 1.000   
 Class :character          1st Qu.: 3.000   
 Mode  :character          Median : 5.000   
                           Mean   : 5.462   
                           3rd Qu.: 8.000   
                           Max.   :10.000   
 heart_rate_bpm_during_attack breathing_rate_breaths_min
 Min.   : 60.0                Min.   :12.00             
 1st Qu.: 89.0                1st Qu.:18.00             
 Median :119.0                Median :25.00             
 Mean   :119.4                Mean   :25.46             
 3rd Qu.:149.0                3rd Qu.:32.00             
 Max.   :179.0                Max.   :39.00             
 sweating_level_1_5  dizziness          medication       
 Min.   :1.000      Length:12000       Length:12000      
 1st Qu.:2.000      Class :character   Class :character  
 Median :3.000      Mode  :character   Mode  :character  
 Mean   :2.987                                           
 3rd Qu.:4.000                                           
 Max.   :5.000                                           
 therapy_sessions_per_month recent_major_life_event
 Min.   :0.000              Length:12000           
 1st Qu.:2.000              Class :character       
 Median :5.000              Mode  :character       
 Mean   :4.518                                     
 3rd Qu.:7.000                                     
 Max.   :9.000                                     
 diet_quality_1_10 severity_of_anxiety_attack_1_10
 Min.   : 1.000    Min.   : 1.000                 
 1st Qu.: 3.000    1st Qu.: 3.000                 
 Median : 5.000    Median : 6.000                 
 Mean   : 5.497    Mean   : 5.508                 
 3rd Qu.: 8.000    3rd Qu.: 8.000                 
 Max.   :10.000    Max.   :10.000                 
if (capture_all_output) {
    print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:07 CST"

3.5 Further Details

if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Detailed Data Summary (skimr) ---\n\n")
}


--- Detailed Data Summary (skimr) ---
skim(anxiety_data_clean_names)
── Data Summary ────────────────────────
                           Values                  
Name                       anxiety_data_clean_names
Number of rows             12000                   
Number of columns          20                      
_______________________                            
Column type frequency:                             
  character                7                       
  numeric                  13                      
________________________                           
Group variables            None                    
if (capture_all_output) {
    print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:08 CST"

4. Detailed Variable Examination (Prepare Phase Visualizations)

4.1 Categorical Variable Analysis

if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Categorical Variable Plots ---\n\n")
}


--- Categorical Variable Plots ---
categorical_vars <- c("gender", "occupation", "smoking", "family_history_of_anxiety",
                     "dizziness", "medication", "recent_major_life_event")

# Generate plots and tables, storing them in a list
categorical_results <- lapply(categorical_vars, function(var) {
  plot_categorical(anxiety_data_clean_names, var)
})
[1] "Frequency Table for gender :"

Female   Male  Other 
  5809   5723    468 
[1] "Frequency Table for occupation :"

    Doctor   Engineer      Other    Student    Teacher 
      2004       1953       1971       1953       1980 
Unemployed 
      2139 
[1] "Frequency Table for smoking :"

  No  Yes 
8417 3583 
[1] "Frequency Table for family_history_of_anxiety :"

  No  Yes 
7179 4821 
[1] "Frequency Table for dizziness :"

  No  Yes 
8406 3594 
[1] "Frequency Table for medication :"

  No  Yes 
9605 2395 
[1] "Frequency Table for recent_major_life_event :"

  No  Yes 
9054 2946 

# Extract just the plots for combining
categorical_plots <- lapply(categorical_results, function(x) x$plot)

# Combine and save
combine_and_save(categorical_plots, file.path(plots_folder, "combined_categorical_plots.png"), type = "categorical")



if (capture_all_output) {
    print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:11 CST"

4.2 Numeric Variable Analysis

if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Numeric Variable Plots ---\n\n")
}


--- Numeric Variable Plots ---
numeric_vars <- c("age", "sleep_hours", "physical_activity_hrs_week",
                 "caffeine_intake_mg_day", "alcohol_consumption_drinks_week",
                 "stress_level_1_10", "heart_rate_bpm_during_attack",
                 "breathing_rate_breaths_min", "sweating_level_1_5",
                 "therapy_sessions_per_month", "diet_quality_1_10",
                 "severity_of_anxiety_attack_1_10")

# Generate plots, storing them in a list
numeric_results <- lapply(numeric_vars, function(var) {
  plot_numeric(anxiety_data_clean_names, var)
})
[1] "Histogram for age"
[1] "Boxplot for age"
[1] "Histogram for sleep_hours"
[1] "Boxplot for sleep_hours"
[1] "Histogram for physical_activity_hrs_week"
[1] "Boxplot for physical_activity_hrs_week"
[1] "Histogram for caffeine_intake_mg_day"
[1] "Boxplot for caffeine_intake_mg_day"
[1] "Histogram for alcohol_consumption_drinks_week"
[1] "Boxplot for alcohol_consumption_drinks_week"
[1] "Histogram for stress_level_1_10"
[1] "Boxplot for stress_level_1_10"
[1] "Histogram for heart_rate_bpm_during_attack"
[1] "Boxplot for heart_rate_bpm_during_attack"
[1] "Histogram for breathing_rate_breaths_min"
[1] "Boxplot for breathing_rate_breaths_min"
[1] "Histogram for sweating_level_1_5"
[1] "Boxplot for sweating_level_1_5"
[1] "Histogram for therapy_sessions_per_month"
[1] "Boxplot for therapy_sessions_per_month"
[1] "Histogram for diet_quality_1_10"
[1] "Boxplot for diet_quality_1_10"
[1] "Histogram for severity_of_anxiety_attack_1_10"
[1] "Boxplot for severity_of_anxiety_attack_1_10"

# Combine and save numeric plots (histograms and boxplots)
combine_and_save(numeric_results, file.path(plots_folder, "combined_numeric_plots.png"), type = "numeric")



if (capture_all_output) {
  print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:17 CST"

4.3 Data Type Conversion Plan

The following variables will be converted to factors in the Process phase:

  • gender: Categorical variable.
  • occupation: Categorical variable.
  • smoking: Categorical (Yes/No).
  • family_history_of_anxiety: Categorical (Yes/No).
  • dizziness: Categorical (Yes/No).
  • medication: Categorical (Yes/No).
  • recent_major_life_event: Categorical (Yes/No).

4.4 Duplicate Check

if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Duplicate Check ---\n\n")
}


--- Duplicate Check ---
duplicates<- anxiety_data_clean_names %>%
  duplicated() %>%
  sum()
print("Number of Duplicate Rows:")
[1] "Number of Duplicate Rows:"
print(duplicates)
[1] 0
if (capture_all_output) {
    print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:17 CST"

4.5 Explicit Missing Value Check

if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Explicit Missing Value Check ---\n\n")
}


--- Explicit Missing Value Check ---
missing_values <- colSums(is.na(anxiety_data_clean_names))
print("Missing Values per Column:")
[1] "Missing Values per Column:"
print(missing_values)
                             id 
                              0 
                            age 
                              0 
                         gender 
                              0 
                     occupation 
                              0 
                    sleep_hours 
                              0 
     physical_activity_hrs_week 
                              0 
         caffeine_intake_mg_day 
                              0 
alcohol_consumption_drinks_week 
                              0 
                        smoking 
                              0 
      family_history_of_anxiety 
                              0 
              stress_level_1_10 
                              0 
   heart_rate_bpm_during_attack 
                              0 
     breathing_rate_breaths_min 
                              0 
             sweating_level_1_5 
                              0 
                      dizziness 
                              0 
                     medication 
                              0 
     therapy_sessions_per_month 
                              0 
        recent_major_life_event 
                              0 
              diet_quality_1_10 
                              0 
severity_of_anxiety_attack_1_10 
                              0 
missing_percentages <- colMeans(is.na(anxiety_data_clean_names)) * 100
print("Percentage of Missing Values per Column:")
[1] "Percentage of Missing Values per Column:"
print(missing_percentages)
                             id 
                              0 
                            age 
                              0 
                         gender 
                              0 
                     occupation 
                              0 
                    sleep_hours 
                              0 
     physical_activity_hrs_week 
                              0 
         caffeine_intake_mg_day 
                              0 
alcohol_consumption_drinks_week 
                              0 
                        smoking 
                              0 
      family_history_of_anxiety 
                              0 
              stress_level_1_10 
                              0 
   heart_rate_bpm_during_attack 
                              0 
     breathing_rate_breaths_min 
                              0 
             sweating_level_1_5 
                              0 
                      dizziness 
                              0 
                     medication 
                              0 
     therapy_sessions_per_month 
                              0 
        recent_major_life_event 
                              0 
              diet_quality_1_10 
                              0 
severity_of_anxiety_attack_1_10 
                              0 
if (capture_all_output) {
  print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:17 CST"

5. Data Processing (Process Phase)

This section details the data cleaning and transformation steps, addressing the issues and plans identified in the Prepare phase.

5.1 Data Type Conversion

if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Data Type Conversion ---\n\n")
}


--- Data Type Conversion ---
# Create a copy for processing
anxiety_data_processed <- anxiety_data_clean_names

# Convert character variables to factors
categorical_vars <- c("gender", "occupation", "smoking", "family_history_of_anxiety",
                     "dizziness", "medication", "recent_major_life_event")

anxiety_data_processed <- anxiety_data_processed %>%
  mutate(across(all_of(categorical_vars), as.factor))

# Verify conversion
str(anxiety_data_processed)
tibble [12,000 × 20] (S3: tbl_df/tbl/data.frame)
 $ id                             : num [1:12000] 1 2 3 4 5 6 7 8 9 10 ...
 $ age                            : num [1:12000] 56 46 32 60 25 38 56 36 40 28 ...
 $ gender                         : Factor w/ 3 levels "Female","Male",..: 1 2 1 2 2 2 2 2 2 1 ...
 $ occupation                     : Factor w/ 6 levels "Doctor","Engineer",..: 3 5 1 1 4 4 1 5 1 1 ...
 $ sleep_hours                    : num [1:12000] 9.6 6.4 6.9 9.2 9.2 6.7 3.8 4.9 6.2 8.3 ...
 $ physical_activity_hrs_week     : num [1:12000] 8.3 7.3 1 3.7 2.5 9.9 7.5 0.5 9 9.3 ...
 $ caffeine_intake_mg_day         : num [1:12000] 175 97 467 471 364 194 411 413 284 148 ...
 $ alcohol_consumption_drinks_week: num [1:12000] 6 6 14 16 2 16 13 4 6 18 ...
 $ smoking                        : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 2 1 1 1 ...
 $ family_history_of_anxiety      : Factor w/ 2 levels "No","Yes": 1 1 1 2 2 2 2 1 1 2 ...
 $ stress_level_1_10              : num [1:12000] 4 3 2 6 7 2 2 3 4 5 ...
 $ heart_rate_bpm_during_attack   : num [1:12000] 145 143 60 94 152 174 81 88 121 145 ...
 $ breathing_rate_breaths_min     : num [1:12000] 33 18 34 19 15 25 22 36 28 12 ...
 $ sweating_level_1_5             : num [1:12000] 3 5 1 1 4 3 4 5 2 4 ...
 $ dizziness                      : Factor w/ 2 levels "No","Yes": 1 2 1 1 1 1 1 1 1 1 ...
 $ medication                     : Factor w/ 2 levels "No","Yes": 1 1 1 2 2 2 1 2 1 1 ...
 $ therapy_sessions_per_month     : num [1:12000] 4 0 7 4 0 2 5 6 0 3 ...
 $ recent_major_life_event        : Factor w/ 2 levels "No","Yes": 2 1 2 2 1 2 2 1 1 1 ...
 $ diet_quality_1_10              : num [1:12000] 9 9 10 5 1 1 10 4 5 10 ...
 $ severity_of_anxiety_attack_1_10: num [1:12000] 10 8 5 8 1 8 10 2 4 4 ...
if (capture_all_output) {
  print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:17 CST"

5.2 Outlier Investigation and Handling

if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Outlier Investigation and Handling ---\n\n")
}


--- Outlier Investigation and Handling ---
# --- sleep_hours ---
# Investigate values < 4
low_sleep <- anxiety_data_processed %>% filter(sleep_hours < 4)
print("Observations with sleep_hours < 4:")
[1] "Observations with sleep_hours < 4:"
print(low_sleep)
# Decision: Keep.  While low, these values are plausible.

# --- physical_activity_hrs_week ---
# Investigate values > 9
high_activity <- anxiety_data_processed %>% filter(physical_activity_hrs_week > 9)
print("Observations with physical_activity_hrs_week > 9:")
[1] "Observations with physical_activity_hrs_week > 9:"
print(high_activity)
# Decision: Keep. These are high but plausible values.

# --- caffeine_intake_mg_day ---
# Investigate values > 400
high_caffeine <- anxiety_data_processed %>% filter(caffeine_intake_mg_day > 400)
print("Observations with caffeine_intake_mg_day > 400:")
[1] "Observations with caffeine_intake_mg_day > 400:"
print(high_caffeine)
# Decision: Keep. These are high, but plausible, values.

# --- alcohol_consumption_drinks_week ---
# Investigate values > 14
high_alcohol <- anxiety_data_processed %>% filter(alcohol_consumption_drinks_week > 14)
print("Observations with alcohol_consumption_drinks_week > 14:")
[1] "Observations with alcohol_consumption_drinks_week > 14:"
print(high_alcohol)
# Decision: Keep. While above recommended limits, they are plausible.

# --- heart_rate_bpm_during_attack ---
# Investigate values < 70 and > 160
low_hr <- anxiety_data_processed %>% filter(heart_rate_bpm_during_attack < 70)
print("Observations with heart_rate_bpm_during_attack < 70:")
[1] "Observations with heart_rate_bpm_during_attack < 70:"
print(low_hr)

high_hr <- anxiety_data_processed %>% filter(heart_rate_bpm_during_attack > 160)
print("Observations with heart_rate_bpm_during_attack > 160:")
[1] "Observations with heart_rate_bpm_during_attack > 160:"
print(high_hr)
# Decision: Keep. After reviewing the context, values are kept.

# --- breathing_rate_breaths_min ---
# Investigate values < 15 and > 35
low_br <- anxiety_data_processed %>% filter(breathing_rate_breaths_min < 15)
print("Observations with breathing_rate_breaths_min < 15:")
[1] "Observations with breathing_rate_breaths_min < 15:"
print(low_br)
high_br <- anxiety_data_processed %>% filter(breathing_rate_breaths_min > 35)
print("Observations with breathing_rate_breaths_min > 35:")
[1] "Observations with breathing_rate_breaths_min > 35:"
print(high_br)
# Decision: Keep. After reviewing the context, values are kept.

if (capture_all_output) {
  print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:18 CST"

5.3. Variable Creation

if (capture_all_output) {
    sink(file = output_file_path, append = TRUE, split = TRUE)
    cat("\n\n--- Variable Creation ---\n\n")
}


--- Variable Creation ---
# --- High Stress Indicator ---
anxiety_data_processed <- anxiety_data_processed %>%
  mutate(high_stress = ifelse(stress_level_1_10 >= 8, 1, 0))

# --- High Severity Indicator ---
anxiety_data_processed <- anxiety_data_processed %>%
  mutate(high_severity = ifelse(severity_of_anxiety_attack_1_10 >= 8, 1, 0))

# --- Untreated Indicator ---
anxiety_data_processed <- anxiety_data_processed %>%
  mutate(untreated = ifelse(high_stress == 1 & high_severity == 1 & therapy_sessions_per_month == 0 & medication == "No", 1, 0))

# --- Low Sleep Indicator ---
anxiety_data_processed <- anxiety_data_processed %>%
      mutate(low_sleep = ifelse(sleep_hours < 7, 1, 0))


# --- High Alcohol Consumption Indicator ---
anxiety_data_processed <- anxiety_data_processed %>%
      mutate(high_alcohol = ifelse( (gender == "Female" & alcohol_consumption_drinks_week >= 8) |
                                     (gender == "Male"   & alcohol_consumption_drinks_week >= 15) |
                                     (gender == "Other" & alcohol_consumption_drinks_week >= 15)
                                   , 1, 0))

# --- High Caffeine Consumption Indicator ---
anxiety_data_processed <- anxiety_data_processed %>%
    mutate(high_caffeine = ifelse(caffeine_intake_mg_day > 400, 1, 0))

#Verify
str(anxiety_data_processed)
tibble [12,000 × 26] (S3: tbl_df/tbl/data.frame)
 $ id                             : num [1:12000] 1 2 3 4 5 6 7 8 9 10 ...
 $ age                            : num [1:12000] 56 46 32 60 25 38 56 36 40 28 ...
 $ gender                         : Factor w/ 3 levels "Female","Male",..: 1 2 1 2 2 2 2 2 2 1 ...
 $ occupation                     : Factor w/ 6 levels "Doctor","Engineer",..: 3 5 1 1 4 4 1 5 1 1 ...
 $ sleep_hours                    : num [1:12000] 9.6 6.4 6.9 9.2 9.2 6.7 3.8 4.9 6.2 8.3 ...
 $ physical_activity_hrs_week     : num [1:12000] 8.3 7.3 1 3.7 2.5 9.9 7.5 0.5 9 9.3 ...
 $ caffeine_intake_mg_day         : num [1:12000] 175 97 467 471 364 194 411 413 284 148 ...
 $ alcohol_consumption_drinks_week: num [1:12000] 6 6 14 16 2 16 13 4 6 18 ...
 $ smoking                        : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 2 1 1 1 ...
 $ family_history_of_anxiety      : Factor w/ 2 levels "No","Yes": 1 1 1 2 2 2 2 1 1 2 ...
 $ stress_level_1_10              : num [1:12000] 4 3 2 6 7 2 2 3 4 5 ...
 $ heart_rate_bpm_during_attack   : num [1:12000] 145 143 60 94 152 174 81 88 121 145 ...
 $ breathing_rate_breaths_min     : num [1:12000] 33 18 34 19 15 25 22 36 28 12 ...
 $ sweating_level_1_5             : num [1:12000] 3 5 1 1 4 3 4 5 2 4 ...
 $ dizziness                      : Factor w/ 2 levels "No","Yes": 1 2 1 1 1 1 1 1 1 1 ...
 $ medication                     : Factor w/ 2 levels "No","Yes": 1 1 1 2 2 2 1 2 1 1 ...
 $ therapy_sessions_per_month     : num [1:12000] 4 0 7 4 0 2 5 6 0 3 ...
 $ recent_major_life_event        : Factor w/ 2 levels "No","Yes": 2 1 2 2 1 2 2 1 1 1 ...
 $ diet_quality_1_10              : num [1:12000] 9 9 10 5 1 1 10 4 5 10 ...
 $ severity_of_anxiety_attack_1_10: num [1:12000] 10 8 5 8 1 8 10 2 4 4 ...
 $ high_stress                    : num [1:12000] 0 0 0 0 0 0 0 0 0 0 ...
 $ high_severity                  : num [1:12000] 1 1 0 1 0 1 1 0 0 0 ...
 $ untreated                      : num [1:12000] 0 0 0 0 0 0 0 0 0 0 ...
 $ low_sleep                      : num [1:12000] 0 1 1 0 0 1 1 1 1 0 ...
 $ high_alcohol                   : num [1:12000] 0 0 1 1 0 1 0 0 0 1 ...
 $ high_caffeine                  : num [1:12000] 0 0 1 1 0 0 1 1 0 0 ...
if (capture_all_output) {
  print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:19 CST"

5.4. Verification

# --- Verification ---
if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Verification ---\n\n")
}


--- Verification ---
# Check for NA's again in the new variables
missing_values_processed <- colSums(is.na(anxiety_data_processed))
print("Missing Values per Column After Processing:")
[1] "Missing Values per Column After Processing:"
print(missing_values_processed)
                             id 
                              0 
                            age 
                              0 
                         gender 
                              0 
                     occupation 
                              0 
                    sleep_hours 
                              0 
     physical_activity_hrs_week 
                              0 
         caffeine_intake_mg_day 
                              0 
alcohol_consumption_drinks_week 
                              0 
                        smoking 
                              0 
      family_history_of_anxiety 
                              0 
              stress_level_1_10 
                              0 
   heart_rate_bpm_during_attack 
                              0 
     breathing_rate_breaths_min 
                              0 
             sweating_level_1_5 
                              0 
                      dizziness 
                              0 
                     medication 
                              0 
     therapy_sessions_per_month 
                              0 
        recent_major_life_event 
                              0 
              diet_quality_1_10 
                              0 
severity_of_anxiety_attack_1_10 
                              0 
                    high_stress 
                              0 
                  high_severity 
                              0 
                      untreated 
                              0 
                      low_sleep 
                              0 
                   high_alcohol 
                              0 
                  high_caffeine 
                              0 
# Check for Duplicates again
duplicates_processed <- anxiety_data_processed %>%
  duplicated() %>%
  sum()
print("Number of Duplicate Rows After Processing:")
[1] "Number of Duplicate Rows After Processing:"
print(duplicates_processed)
[1] 0
if (capture_all_output) {
  print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:19 CST"

6. Data Analysis (Analyze Phase)

6.1. Descriptive Statistics (Targeted Groups)

# --- Descriptive Statistics (Targeted Groups) ---
if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Descriptive Statistics (Targeted Groups) ---\n\n")
}


--- Descriptive Statistics (Targeted Groups) ---
library(knitr) # Make sure knitr is loaded

# --- Overall Descriptive Statistics ---
cat("\nOverall Descriptive Statistics:\n")

Overall Descriptive Statistics:
print(kable(skim(anxiety_data_processed), format = "markdown"))
skim_type skim_variable n_missing complete_rate factor.ordered factor.n_unique factor.top_counts numeric.mean numeric.sd numeric.p0 numeric.p25 numeric.p50 numeric.p75 numeric.p100 numeric.hist
factor gender 0 1 FALSE 3 Fem: 5809, Mal: 5723, Oth: 468 NA NA NA NA NA NA NA NA
factor occupation 0 1 FALSE 6 Une: 2139, Doc: 2004, Tea: 1980, Oth: 1971 NA NA NA NA NA NA NA NA
factor smoking 0 1 FALSE 2 No: 8417, Yes: 3583 NA NA NA NA NA NA NA NA
factor family_history_of_anxiety 0 1 FALSE 2 No: 7179, Yes: 4821 NA NA NA NA NA NA NA NA
factor dizziness 0 1 FALSE 2 No: 8406, Yes: 3594 NA NA NA NA NA NA NA NA
factor medication 0 1 FALSE 2 No: 9605, Yes: 2395 NA NA NA NA NA NA NA NA
factor recent_major_life_event 0 1 FALSE 2 No: 9054, Yes: 2946 NA NA NA NA NA NA NA NA
numeric id 0 1 NA NA NA 6000.5000000 3464.2459497 1 3000.75 6000.5 9000.250 12000 ▇▇▇▇▇
numeric age 0 1 NA NA NA 40.9667500 13.4732799 18 29.00 41.0 53.000 64 ▇▇▇▇▇
numeric sleep_hours 0 1 NA NA NA 6.4826500 2.0148852 3 4.80 6.5 8.200 10 ▇▇▇▇▇
numeric physical_activity_hrs_week 0 1 NA NA NA 5.0308917 2.8890002 0 2.50 5.0 7.525 10 ▇▇▇▇▇
numeric caffeine_intake_mg_day 0 1 NA NA NA 246.6960833 144.4870713 0 122.00 244.0 371.000 499 ▇▇▇▇▇
numeric alcohol_consumption_drinks_week 0 1 NA NA NA 9.4928333 5.7693635 0 5.00 9.0 15.000 19 ▇▇▇▇▇
numeric stress_level_1_10 0 1 NA NA NA 5.4622500 2.8972011 1 3.00 5.0 8.000 10 ▇▇▇▇▇
numeric heart_rate_bpm_during_attack 0 1 NA NA NA 119.3985000 34.8067114 60 89.00 119.0 149.000 179 ▇▇▇▇▇
numeric breathing_rate_breaths_min 0 1 NA NA NA 25.4623333 8.0906862 12 18.00 25.0 32.000 39 ▇▆▇▆▇
numeric sweating_level_1_5 0 1 NA NA NA 2.9874167 1.4144817 1 2.00 3.0 4.000 5 ▇▇▇▇▇
numeric therapy_sessions_per_month 0 1 NA NA NA 4.5184167 2.8660098 0 2.00 5.0 7.000 9 ▇▇▇▇▇
numeric diet_quality_1_10 0 1 NA NA NA 5.4973333 2.8675794 1 3.00 5.0 8.000 10 ▇▇▇▇▇
numeric severity_of_anxiety_attack_1_10 0 1 NA NA NA 5.5075833 2.8586635 1 3.00 6.0 8.000 10 ▇▇▇▇▇
numeric high_stress 0 1 NA NA NA 0.2951667 0.4561367 0 0.00 0.0 1.000 1 ▇▁▁▁▃
numeric high_severity 0 1 NA NA NA 0.2970833 0.4569926 0 0.00 0.0 1.000 1 ▇▁▁▁▃
numeric untreated 0 1 NA NA NA 0.0057500 0.0756136 0 0.00 0.0 0.000 1 ▇▁▁▁▁
numeric low_sleep 0 1 NA NA NA 0.5736667 0.4945641 0 0.00 1.0 1.000 1 ▆▁▁▁▇
numeric high_alcohol 0 1 NA NA NA 0.4219167 0.4938859 0 0.00 0.0 1.000 1 ▇▁▁▁▆
numeric high_caffeine 0 1 NA NA NA 0.1913333 0.3933672 0 0.00 0.0 0.000 1 ▇▁▁▁▂


# --- High Stress Group (stress_level_1_10 >= 8) ---
cat("\nHigh Stress Group (stress_level_1_10 >= 8):\n")

High Stress Group (stress_level_1_10 >= 8):
high_stress_skim <- anxiety_data_processed %>%
  filter(high_stress == 1) %>%
  skim()
print(kable(high_stress_skim, format = "markdown"))
skim_type skim_variable n_missing complete_rate factor.ordered factor.n_unique factor.top_counts numeric.mean numeric.sd numeric.p0 numeric.p25 numeric.p50 numeric.p75 numeric.p100 numeric.hist
factor gender 0 1 FALSE 3 Fem: 1714, Mal: 1684, Oth: 144 NA NA NA NA NA NA NA NA
factor occupation 0 1 FALSE 6 Une: 643, Doc: 618, Oth: 593, Tea: 583 NA NA NA NA NA NA NA NA
factor smoking 0 1 FALSE 2 No: 2498, Yes: 1044 NA NA NA NA NA NA NA NA
factor family_history_of_anxiety 0 1 FALSE 2 No: 2167, Yes: 1375 NA NA NA NA NA NA NA NA
factor dizziness 0 1 FALSE 2 No: 2510, Yes: 1032 NA NA NA NA NA NA NA NA
factor medication 0 1 FALSE 2 No: 2845, Yes: 697 NA NA NA NA NA NA NA NA
factor recent_major_life_event 0 1 FALSE 2 No: 2653, Yes: 889 NA NA NA NA NA NA NA NA
numeric id 0 1 NA NA NA 5983.1894410 3465.0240856 21 2960.25 6028.0 8894.75 11999 ▇▇▇▇▇
numeric age 0 1 NA NA NA 41.4212309 13.4551408 18 30.00 42.0 53.00 64 ▇▇▇▇▇
numeric sleep_hours 0 1 NA NA NA 6.4819029 2.0236801 3 4.70 6.5 8.20 10 ▇▇▇▇▇
numeric physical_activity_hrs_week 0 1 NA NA NA 5.0207228 2.8872153 0 2.60 5.0 7.50 10 ▇▇▇▇▇
numeric caffeine_intake_mg_day 0 1 NA NA NA 250.9618859 145.5021705 0 126.00 249.0 376.00 499 ▇▇▇▇▇
numeric alcohol_consumption_drinks_week 0 1 NA NA NA 9.5118577 5.7096509 0 5.00 9.0 14.00 19 ▇▇▇▇▇
numeric stress_level_1_10 0 1 NA NA NA 9.0271033 0.8145455 8 8.00 9.0 10.00 10 ▇▁▇▁▇
numeric heart_rate_bpm_during_attack 0 1 NA NA NA 118.8740824 34.6482622 60 89.00 119.0 150.00 179 ▇▇▇▇▇
numeric breathing_rate_breaths_min 0 1 NA NA NA 25.4271598 8.0480888 12 19.00 25.0 32.00 39 ▇▇▇▆▇
numeric sweating_level_1_5 0 1 NA NA NA 2.9664032 1.4169070 1 2.00 3.0 4.00 5 ▇▇▇▇▇
numeric therapy_sessions_per_month 0 1 NA NA NA 4.5982496 2.8629285 0 2.00 5.0 7.00 9 ▇▇▇▇▇
numeric diet_quality_1_10 0 1 NA NA NA 5.5143986 2.8628030 1 3.00 6.0 8.00 10 ▇▇▇▇▇
numeric severity_of_anxiety_attack_1_10 0 1 NA NA NA 5.5203275 2.8677937 1 3.00 5.0 8.00 10 ▇▇▇▇▇
numeric high_stress 0 1 NA NA NA 1.0000000 0.0000000 1 1.00 1.0 1.00 1 ▁▁▇▁▁
numeric high_severity 0 1 NA NA NA 0.3043478 0.4601956 0 0.00 0.0 1.00 1 ▇▁▁▁▃
numeric untreated 0 1 NA NA NA 0.0194805 0.1382260 0 0.00 0.0 0.00 1 ▇▁▁▁▁
numeric low_sleep 0 1 NA NA NA 0.5705816 0.4950631 0 0.00 1.0 1.00 1 ▆▁▁▁▇
numeric high_alcohol 0 1 NA NA NA 0.4223602 0.4940050 0 0.00 0.0 1.00 1 ▇▁▁▁▆
numeric high_caffeine 0 1 NA NA NA 0.2027103 0.4020752 0 0.00 0.0 0.00 1 ▇▁▁▁▂

# --- High Severity Group (severity_of_anxiety_attack_1_10 >= 8) ---
cat("\nHigh Severity Group (severity_of_anxiety_attack_1_10 >= 8):\n")

High Severity Group (severity_of_anxiety_attack_1_10 >= 8):
high_severity_skim <- anxiety_data_processed %>%
  filter(high_severity == 1) %>%
  skim()
print(kable(high_severity_skim, format = "markdown"))
skim_type skim_variable n_missing complete_rate factor.ordered factor.n_unique factor.top_counts numeric.mean numeric.sd numeric.p0 numeric.p25 numeric.p50 numeric.p75 numeric.p100 numeric.hist
factor gender 0 1 FALSE 3 Fem: 1720, Mal: 1707, Oth: 138 NA NA NA NA NA NA NA NA
factor occupation 0 1 FALSE 6 Une: 650, Oth: 595, Tea: 587, Eng: 584 NA NA NA NA NA NA NA NA
factor smoking 0 1 FALSE 2 No: 2530, Yes: 1035 NA NA NA NA NA NA NA NA
factor family_history_of_anxiety 0 1 FALSE 2 No: 2105, Yes: 1460 NA NA NA NA NA NA NA NA
factor dizziness 0 1 FALSE 2 No: 2448, Yes: 1117 NA NA NA NA NA NA NA NA
factor medication 0 1 FALSE 2 No: 2862, Yes: 703 NA NA NA NA NA NA NA NA
factor recent_major_life_event 0 1 FALSE 2 No: 2711, Yes: 854 NA NA NA NA NA NA NA NA
numeric id 0 1 NA NA NA 5941.5506311 3468.7468716 1 2921.0 5874.0 8941.0 11998 ▇▇▇▇▇
numeric age 0 1 NA NA NA 40.7542777 13.5025743 18 29.0 41.0 52.0 64 ▇▇▇▇▇
numeric sleep_hours 0 1 NA NA NA 6.4638710 2.0430583 3 4.7 6.4 8.2 10 ▇▇▇▇▇
numeric physical_activity_hrs_week 0 1 NA NA NA 5.1044320 2.8752890 0 2.6 5.1 7.7 10 ▇▇▇▇▇
numeric caffeine_intake_mg_day 0 1 NA NA NA 247.4659187 144.4413647 0 122.0 246.0 371.0 499 ▇▇▇▇▇
numeric alcohol_consumption_drinks_week 0 1 NA NA NA 9.4737728 5.7484883 0 5.0 9.0 14.0 19 ▇▇▇▇▇
numeric stress_level_1_10 0 1 NA NA NA 5.4995792 2.9142847 1 3.0 6.0 8.0 10 ▇▇▇▇▇
numeric heart_rate_bpm_during_attack 0 1 NA NA NA 119.2244039 35.1393429 60 88.0 119.0 150.0 179 ▇▇▇▇▇
numeric breathing_rate_breaths_min 0 1 NA NA NA 25.5481066 8.1092256 12 19.0 26.0 33.0 39 ▇▆▇▆▇
numeric sweating_level_1_5 0 1 NA NA NA 3.0067321 1.4138007 1 2.0 3.0 4.0 5 ▇▇▇▇▇
numeric therapy_sessions_per_month 0 1 NA NA NA 4.4796634 2.8818765 0 2.0 4.0 7.0 9 ▇▇▇▇▇
numeric diet_quality_1_10 0 1 NA NA NA 5.4712482 2.8523477 1 3.0 5.0 8.0 10 ▇▇▇▇▇
numeric severity_of_anxiety_attack_1_10 0 1 NA NA NA 9.0000000 0.8161529 8 8.0 9.0 10.0 10 ▇▁▇▁▇
numeric high_stress 0 1 NA NA NA 0.3023843 0.4593552 0 0.0 0.0 1.0 1 ▇▁▁▁▃
numeric high_severity 0 1 NA NA NA 1.0000000 0.0000000 1 1.0 1.0 1.0 1 ▁▁▇▁▁
numeric untreated 0 1 NA NA NA 0.0193548 0.1377881 0 0.0 0.0 0.0 1 ▇▁▁▁▁
numeric low_sleep 0 1 NA NA NA 0.5733520 0.4946596 0 0.0 1.0 1.0 1 ▆▁▁▁▇
numeric high_alcohol 0 1 NA NA NA 0.4185133 0.4933844 0 0.0 0.0 1.0 1 ▇▁▁▁▆
numeric high_caffeine 0 1 NA NA NA 0.1921459 0.3940424 0 0.0 0.0 0.0 1 ▇▁▁▁▂


# --- Untreated Group (high_stress, high_severity, no therapy/medication) ---
cat("\nUntreated Group (High Stress, High Severity, No Therapy/Medication):\n")

Untreated Group (High Stress, High Severity, No Therapy/Medication):
untreated_skim <- anxiety_data_processed %>%
  filter(untreated == 1) %>%
  skim()
print(kable(untreated_skim, format = "markdown"))
skim_type skim_variable n_missing complete_rate factor.ordered factor.n_unique factor.top_counts numeric.mean numeric.sd numeric.p0 numeric.p25 numeric.p50 numeric.p75 numeric.p100 numeric.hist
factor gender 0 1 FALSE 3 Mal: 37, Fem: 31, Oth: 1 NA NA NA NA NA NA NA NA
factor occupation 0 1 FALSE 6 Doc: 14, Eng: 13, Oth: 13, Une: 12 NA NA NA NA NA NA NA NA
factor smoking 0 1 FALSE 2 No: 47, Yes: 22 NA NA NA NA NA NA NA NA
factor family_history_of_anxiety 0 1 FALSE 2 No: 39, Yes: 30 NA NA NA NA NA NA NA NA
factor dizziness 0 1 FALSE 2 No: 47, Yes: 22 NA NA NA NA NA NA NA NA
factor medication 0 1 FALSE 1 No: 69, Yes: 0 NA NA NA NA NA NA NA NA
factor recent_major_life_event 0 1 FALSE 2 No: 53, Yes: 16 NA NA NA NA NA NA NA NA
numeric id 0 1 NA NA NA 5219.0289855 3847.4373479 63.0 1707.0 4542.0 9409.0 11872 ▇▅▃▃▆
numeric age 0 1 NA NA NA 39.6666667 12.6568589 18.0 30.0 40.0 50.0 64 ▇▇▇▇▅
numeric sleep_hours 0 1 NA NA NA 6.5478261 2.1423330 3.0 4.8 6.7 8.4 10 ▇▆▅▇▇
numeric physical_activity_hrs_week 0 1 NA NA NA 5.5652174 2.9555942 0.3 2.7 5.9 8.3 10 ▅▅▇▆▇
numeric caffeine_intake_mg_day 0 1 NA NA NA 257.5362319 149.7427775 1.0 149.0 254.0 377.0 495 ▆▆▆▆▇
numeric alcohol_consumption_drinks_week 0 1 NA NA NA 9.8985507 5.3030095 0.0 5.0 10.0 14.0 19 ▃▆▇▃▇
numeric stress_level_1_10 0 1 NA NA NA 8.8985507 0.8427010 8.0 8.0 9.0 10.0 10 ▇▁▆▁▆
numeric heart_rate_bpm_during_attack 0 1 NA NA NA 109.1014493 33.2057512 61.0 79.0 107.0 135.0 175 ▇▅▇▆▂
numeric breathing_rate_breaths_min 0 1 NA NA NA 27.2463768 8.1842852 12.0 21.0 29.0 34.0 39 ▅▃▅▆▇
numeric sweating_level_1_5 0 1 NA NA NA 3.0144928 1.4500786 1.0 2.0 3.0 4.0 5 ▇▆▇▆▇
numeric therapy_sessions_per_month 0 1 NA NA NA 0.0000000 0.0000000 0.0 0.0 0.0 0.0 0 ▁▁▇▁▁
numeric diet_quality_1_10 0 1 NA NA NA 5.2028986 2.9234333 1.0 2.0 5.0 7.0 10 ▇▅▇▆▅
numeric severity_of_anxiety_attack_1_10 0 1 NA NA NA 9.0000000 0.8401681 8.0 8.0 9.0 10.0 10 ▇▁▇▁▇
numeric high_stress 0 1 NA NA NA 1.0000000 0.0000000 1.0 1.0 1.0 1.0 1 ▁▁▇▁▁
numeric high_severity 0 1 NA NA NA 1.0000000 0.0000000 1.0 1.0 1.0 1.0 1 ▁▁▇▁▁
numeric untreated 0 1 NA NA NA 1.0000000 0.0000000 1.0 1.0 1.0 1.0 1 ▁▁▇▁▁
numeric low_sleep 0 1 NA NA NA 0.5362319 0.5023389 0.0 0.0 1.0 1.0 1 ▇▁▁▁▇
numeric high_alcohol 0 1 NA NA NA 0.4347826 0.4993602 0.0 0.0 0.0 1.0 1 ▇▁▁▁▆
numeric high_caffeine 0 1 NA NA NA 0.2463768 0.4340574 0.0 0.0 0.0 0.0 1 ▇▁▁▁▂


# --- Low Sleep Group (sleep_hours < 7) ---
cat("\nLow Sleep Group (sleep_hours < 7):\n")

Low Sleep Group (sleep_hours < 7):
low_sleep_skim <- anxiety_data_processed %>%
  filter(low_sleep == 1) %>%
  skim()
print(kable(low_sleep_skim, format = "markdown"))
skim_type skim_variable n_missing complete_rate factor.ordered factor.n_unique factor.top_counts numeric.mean numeric.sd numeric.p0 numeric.p25 numeric.p50 numeric.p75 numeric.p100 numeric.hist
factor gender 0 1 FALSE 3 Fem: 3324, Mal: 3281, Oth: 279 NA NA NA NA NA NA NA NA
factor occupation 0 1 FALSE 6 Une: 1236, Doc: 1155, Stu: 1143, Oth: 1135 NA NA NA NA NA NA NA NA
factor smoking 0 1 FALSE 2 No: 4894, Yes: 1990 NA NA NA NA NA NA NA NA
factor family_history_of_anxiety 0 1 FALSE 2 No: 4095, Yes: 2789 NA NA NA NA NA NA NA NA
factor dizziness 0 1 FALSE 2 No: 4805, Yes: 2079 NA NA NA NA NA NA NA NA
factor medication 0 1 FALSE 2 No: 5515, Yes: 1369 NA NA NA NA NA NA NA NA
factor recent_major_life_event 0 1 FALSE 2 No: 5194, Yes: 1690 NA NA NA NA NA NA NA NA
numeric id 0 1 NA NA NA 6029.9456711 3450.6706995 2 3058.75 6044.5 9008.50 12000.0 ▇▇▇▇▇
numeric age 0 1 NA NA NA 40.8782684 13.3999377 18 29.00 41.0 52.00 64.0 ▇▇▇▇▇
numeric sleep_hours 0 1 NA NA NA 4.9948576 1.1452000 3 4.00 5.0 6.00 6.9 ▇▇▇▇▇
numeric physical_activity_hrs_week 0 1 NA NA NA 5.0198141 2.8583361 0 2.60 5.0 7.50 10.0 ▇▇▇▇▇
numeric caffeine_intake_mg_day 0 1 NA NA NA 246.2486926 144.6147327 0 120.00 244.0 372.00 499.0 ▇▇▇▇▇
numeric alcohol_consumption_drinks_week 0 1 NA NA NA 9.3999128 5.7901965 0 4.00 9.0 14.25 19.0 ▇▇▇▇▇
numeric stress_level_1_10 0 1 NA NA NA 5.4402963 2.9002613 1 3.00 5.0 8.00 10.0 ▇▇▇▇▇
numeric heart_rate_bpm_during_attack 0 1 NA NA NA 119.9251888 34.6850391 60 90.00 120.0 150.00 179.0 ▇▇▇▇▇
numeric breathing_rate_breaths_min 0 1 NA NA NA 25.5261476 8.1236118 12 19.00 25.0 33.00 39.0 ▇▇▇▆▇
numeric sweating_level_1_5 0 1 NA NA NA 2.9818420 1.4096207 1 2.00 3.0 4.00 5.0 ▇▇▇▇▇
numeric therapy_sessions_per_month 0 1 NA NA NA 4.5302150 2.8511607 0 2.00 5.0 7.00 9.0 ▇▇▇▇▇
numeric diet_quality_1_10 0 1 NA NA NA 5.4841662 2.8586557 1 3.00 5.0 8.00 10.0 ▇▇▇▇▇
numeric severity_of_anxiety_attack_1_10 0 1 NA NA NA 5.5017432 2.8589023 1 3.00 5.0 8.00 10.0 ▇▇▇▇▇
numeric high_stress 0 1 NA NA NA 0.2935793 0.4554346 0 0.00 0.0 1.00 1.0 ▇▁▁▁▃
numeric high_severity 0 1 NA NA NA 0.2969204 0.4569344 0 0.00 0.0 1.00 1.0 ▇▁▁▁▃
numeric untreated 0 1 NA NA NA 0.0053748 0.0731209 0 0.00 0.0 0.00 1.0 ▇▁▁▁▁
numeric low_sleep 0 1 NA NA NA 1.0000000 0.0000000 1 1.00 1.0 1.00 1.0 ▁▁▇▁▁
numeric high_alcohol 0 1 NA NA NA 0.4171993 0.4931322 0 0.00 0.0 1.00 1.0 ▇▁▁▁▆
numeric high_caffeine 0 1 NA NA NA 0.1911679 0.3932496 0 0.00 0.0 0.00 1.0 ▇▁▁▁▂

# --- High Alcohol Group ---
cat("\nHigh Alcohol Group:\n")

High Alcohol Group:
high_alcohol_skim <- anxiety_data_processed %>%
  filter(high_alcohol == 1) %>%
  skim()
print(kable(high_alcohol_skim, format = "markdown"))
skim_type skim_variable n_missing complete_rate factor.ordered factor.n_unique factor.top_counts numeric.mean numeric.sd numeric.p0 numeric.p25 numeric.p50 numeric.p75 numeric.p100 numeric.hist
factor gender 0 1 FALSE 3 Fem: 3501, Mal: 1439, Oth: 123 NA NA NA NA NA NA NA NA
factor occupation 0 1 FALSE 6 Une: 868, Oth: 864, Stu: 854, Doc: 845 NA NA NA NA NA NA NA NA
factor smoking 0 1 FALSE 2 No: 3553, Yes: 1510 NA NA NA NA NA NA NA NA
factor family_history_of_anxiety 0 1 FALSE 2 No: 3042, Yes: 2021 NA NA NA NA NA NA NA NA
factor dizziness 0 1 FALSE 2 No: 3584, Yes: 1479 NA NA NA NA NA NA NA NA
factor medication 0 1 FALSE 2 No: 4036, Yes: 1027 NA NA NA NA NA NA NA NA
factor recent_major_life_event 0 1 FALSE 2 No: 3785, Yes: 1278 NA NA NA NA NA NA NA NA
numeric id 0 1 NA NA NA 6067.8498914 3458.2837367 3 3034.0 6196.0 9031.5 11998 ▇▇▇▇▇
numeric age 0 1 NA NA NA 40.9691882 13.4769158 18 30.0 41.0 52.0 64 ▇▇▇▇▇
numeric sleep_hours 0 1 NA NA NA 6.5171440 2.0199407 3 4.8 6.5 8.3 10 ▇▇▇▇▇
numeric physical_activity_hrs_week 0 1 NA NA NA 5.0041872 2.8816286 0 2.5 5.0 7.5 10 ▇▇▇▇▇
numeric caffeine_intake_mg_day 0 1 NA NA NA 244.5083942 143.8814713 0 120.5 239.0 367.0 499 ▇▇▇▇▇
numeric alcohol_consumption_drinks_week 0 1 NA NA NA 14.5475015 3.4412816 8 12.0 15.0 17.0 19 ▅▂▂▅▇
numeric stress_level_1_10 0 1 NA NA NA 5.4799526 2.9014402 1 3.0 5.0 8.0 10 ▇▇▇▇▇
numeric heart_rate_bpm_during_attack 0 1 NA NA NA 118.6662058 34.7234144 60 88.0 118.0 149.0 179 ▇▇▇▇▇
numeric breathing_rate_breaths_min 0 1 NA NA NA 25.4270196 8.1594974 12 18.0 26.0 33.0 39 ▇▆▇▆▇
numeric sweating_level_1_5 0 1 NA NA NA 2.9812364 1.4141589 1 2.0 3.0 4.0 5 ▇▇▇▇▇
numeric therapy_sessions_per_month 0 1 NA NA NA 4.5018764 2.8786786 0 2.0 4.0 7.0 9 ▇▇▇▇▇
numeric diet_quality_1_10 0 1 NA NA NA 5.5328856 2.8585885 1 3.0 6.0 8.0 10 ▇▇▇▇▇
numeric severity_of_anxiety_attack_1_10 0 1 NA NA NA 5.4959510 2.8408902 1 3.0 5.0 8.0 10 ▇▇▇▇▇
numeric high_stress 0 1 NA NA NA 0.2954770 0.4563019 0 0.0 0.0 1.0 1 ▇▁▁▁▃
numeric high_severity 0 1 NA NA NA 0.2946869 0.4559469 0 0.0 0.0 1.0 1 ▇▁▁▁▃
numeric untreated 0 1 NA NA NA 0.0059253 0.0767554 0 0.0 0.0 0.0 1 ▇▁▁▁▁
numeric low_sleep 0 1 NA NA NA 0.5672526 0.4955054 0 0.0 1.0 1.0 1 ▆▁▁▁▇
numeric high_alcohol 0 1 NA NA NA 1.0000000 0.0000000 1 1.0 1.0 1.0 1 ▁▁▇▁▁
numeric high_caffeine 0 1 NA NA NA 0.1860557 0.3891900 0 0.0 0.0 0.0 1 ▇▁▁▁▂


# --- High Caffeine Group ---
cat("\nHigh Caffeine Group:\n")

High Caffeine Group:
high_caffeine_skim <- anxiety_data_processed %>%
  filter(high_caffeine == 1) %>%
  skim()
print(kable(high_caffeine_skim, format = "markdown"))
skim_type skim_variable n_missing complete_rate factor.ordered factor.n_unique factor.top_counts numeric.mean numeric.sd numeric.p0 numeric.p25 numeric.p50 numeric.p75 numeric.p100 numeric.hist
factor gender 0 1 FALSE 3 Fem: 1104, Mal: 1093, Oth: 99 NA NA NA NA NA NA NA NA
factor occupation 0 1 FALSE 6 Une: 396, Oth: 391, Stu: 383, Tea: 379 NA NA NA NA NA NA NA NA
factor smoking 0 1 FALSE 2 No: 1603, Yes: 693 NA NA NA NA NA NA NA NA
factor family_history_of_anxiety 0 1 FALSE 2 No: 1375, Yes: 921 NA NA NA NA NA NA NA NA
factor dizziness 0 1 FALSE 2 No: 1610, Yes: 686 NA NA NA NA NA NA NA NA
factor medication 0 1 FALSE 2 No: 1819, Yes: 477 NA NA NA NA NA NA NA NA
factor recent_major_life_event 0 1 FALSE 2 No: 1703, Yes: 593 NA NA NA NA NA NA NA NA
numeric id 0 1 NA NA NA 5948.9320557 3507.6717992 3 2859.0 5900.5 8972.25 11997 ▇▇▇▇▇
numeric age 0 1 NA NA NA 40.7639373 13.3314060 18 29.0 41.0 52.00 64 ▇▇▇▇▇
numeric sleep_hours 0 1 NA NA NA 6.4772213 1.9866656 3 4.8 6.5 8.10 10 ▇▇▇▇▆
numeric physical_activity_hrs_week 0 1 NA NA NA 5.0055749 2.9230501 0 2.5 4.9 7.60 10 ▇▇▇▇▇
numeric caffeine_intake_mg_day 0 1 NA NA NA 450.0357143 29.0605938 401 424.0 450.0 476.00 499 ▇▇▆▇▇
numeric alcohol_consumption_drinks_week 0 1 NA NA NA 9.4242160 5.8163174 0 4.0 9.0 14.00 19 ▇▇▇▇▇
numeric stress_level_1_10 0 1 NA NA NA 5.5479094 2.9277971 1 3.0 6.0 8.00 10 ▇▇▇▇▇
numeric heart_rate_bpm_during_attack 0 1 NA NA NA 119.3828397 34.8738685 60 88.0 119.0 150.00 179 ▇▇▇▇▇
numeric breathing_rate_breaths_min 0 1 NA NA NA 25.5953833 8.1093053 12 19.0 25.0 33.00 39 ▇▆▇▆▇
numeric sweating_level_1_5 0 1 NA NA NA 2.9947735 1.4264750 1 2.0 3.0 4.00 5 ▇▇▇▇▇
numeric therapy_sessions_per_month 0 1 NA NA NA 4.6049652 2.8410854 0 2.0 5.0 7.00 9 ▇▇▇▇▇
numeric diet_quality_1_10 0 1 NA NA NA 5.5587979 2.8532794 1 3.0 6.0 8.00 10 ▇▇▇▇▇
numeric severity_of_anxiety_attack_1_10 0 1 NA NA NA 5.5418118 2.8288882 1 3.0 6.0 8.00 10 ▇▇▇▇▇
numeric high_stress 0 1 NA NA NA 0.3127178 0.4637014 0 0.0 0.0 1.00 1 ▇▁▁▁▃
numeric high_severity 0 1 NA NA NA 0.2983449 0.4576314 0 0.0 0.0 1.00 1 ▇▁▁▁▃
numeric untreated 0 1 NA NA NA 0.0074042 0.0857471 0 0.0 0.0 0.00 1 ▇▁▁▁▁
numeric low_sleep 0 1 NA NA NA 0.5731707 0.4947248 0 0.0 1.0 1.00 1 ▆▁▁▁▇
numeric high_alcohol 0 1 NA NA NA 0.4102787 0.4919914 0 0.0 0.0 1.00 1 ▇▁▁▁▆
numeric high_caffeine 0 1 NA NA NA 1.0000000 0.0000000 1 1.0 1.0 1.00 1 ▁▁▇▁▁

# --- Specific Statistics for Key Questions ---
# Create a data frame to store these results
key_stats <- data.frame(
  Question = character(),
  Statistic = character(),
  Value = numeric(),
  stringsAsFactors = FALSE
)

# Question 1: Percentage with severe anxiety attacks in high-stress group

q1_result <- anxiety_data_processed %>%
  filter(high_stress == 1) %>%
  summarize(percent_high_severity = mean(high_severity) * 100)
key_stats <- rbind(key_stats, data.frame(Question = "Q1", Statistic = "Percent High Severity (High Stress)", Value = q1_result$percent_high_severity))


# Question 3: Proportion untreated in high-stress/high-severity group

q3_result <- anxiety_data_processed %>%
  filter(high_stress == 1, high_severity == 1) %>%
  summarize(proportion_untreated = mean(untreated) * 100)
key_stats <- rbind(key_stats, data.frame(Question = "Q3", Statistic = "Percent Untreated (High Stress/Severity)", Value = q3_result$proportion_untreated))


# Question 8: average heart rate and breathing rate
q8_high_result <- anxiety_data_processed %>%
    filter(severity_of_anxiety_attack_1_10 >= 8) %>%
    summarise(average_heart_rate = mean(heart_rate_bpm_during_attack),
              average_breathing_rate = mean(breathing_rate_breaths_min))
key_stats <- rbind(key_stats, data.frame(Question = "Q8 (High)", Statistic = "Average Heart Rate", Value = q8_high_result$average_heart_rate))
key_stats <- rbind(key_stats, data.frame(Question = "Q8 (High)", Statistic = "Average Breathing Rate", Value = q8_high_result$average_breathing_rate))


q8_low_result <- anxiety_data_processed %>%
    filter(severity_of_anxiety_attack_1_10 < 4) %>%
    summarise(average_heart_rate = mean(heart_rate_bpm_during_attack),
              average_breathing_rate = mean(breathing_rate_breaths_min))
key_stats <- rbind(key_stats, data.frame(Question = "Q8 (Low)", Statistic = "Average Heart Rate", Value = q8_low_result$average_heart_rate))
key_stats <- rbind(key_stats, data.frame(Question = "Q8 (Low)", Statistic = "Average Breathing Rate", Value = q8_low_result$average_breathing_rate))

# Question 9: median reported severity_of_anxiety_attack_1_10 of those in therapy
q9_result <- anxiety_data_processed %>%
    filter(therapy_sessions_per_month > 0) %>%
    summarise(median_severity_with_therapy = median(severity_of_anxiety_attack_1_10))
key_stats <- rbind(key_stats, data.frame(Question = "Q9", Statistic = "Median Severity (With Therapy)", Value = q9_result$median_severity_with_therapy))


cat("\nKey Statistics Summary:\n")

Key Statistics Summary:
print(kable(key_stats, format = "markdown"))
Question Statistic Value
Q1 Percent High Severity (High Stress) 30.434783
Q3 Percent Untreated (High Stress/Severity) 6.400742
Q8 (High) Average Heart Rate 119.224404
Q8 (High) Average Breathing Rate 25.548107
Q8 (Low) Average Heart Rate 119.635797
Q8 (Low) Average Breathing Rate 25.474653
Q9 Median Severity (With Therapy) 6.000000


if (capture_all_output) {
  print(Sys.time())
  sink()
}
[1] "2025-02-07 22:21:22 CST"

6.2. Visualizations

# --- Visualizations ---
if (capture_all_output) {
  sink(file = output_file_path, append = TRUE, split = TRUE)
  cat("\n\n--- Visualizations ---\n\n")
}


--- Visualizations ---
# --- Stress Level vs. Anxiety Severity (Boxplot) ---
plot_stress_severity <- ggplot(anxiety_data_processed, aes(x = factor(high_stress), y = severity_of_anxiety_attack_1_10)) +
  geom_boxplot() +
  labs(title = "Anxiety Severity by High Stress",
       x = "High Stress (0 = No, 1 = Yes)",
       y = "Severity of Anxiety Attack (1-10)")
# Keep print statement for console output
print(plot_stress_severity)


# --- Untreated vs. Treated (Boxplot) ---
plot_untreated_severity <- ggplot(anxiety_data_processed, aes(x = factor(untreated), y = severity_of_anxiety_attack_1_10)) +
    geom_boxplot() +
    labs(title = "Anxiety Severity by Untreated Status",
         x = "Untreated (0 = No, 1 = Yes)",
         y = "Severity of Anxiety Attack (1-10)")
print(plot_untreated_severity)


# --- Lifestyle Factors vs. Anxiety Severity (Scatterplots) ---

plot_lifestyle_vs_severity <- function(data, lifestyle_var) {
  plot <- ggplot(data, aes(x = .data[[lifestyle_var]], y = severity_of_anxiety_attack_1_10)) +
    geom_point(alpha = 0.3) +
    geom_smooth(method = "lm", se = FALSE) +
    labs(title = paste("Anxiety Severity vs.", lifestyle_var),
         x = lifestyle_var,
         y = "Severity of Anxiety Attack (1-10)")
  if (capture_all_output) { # Only print if capture_all_output is TRUE
        print(plot)
    }
  return(plot)
}

lifestyle_vars <- c("sleep_hours", "physical_activity_hrs_week", "caffeine_intake_mg_day", "alcohol_consumption_drinks_week", "diet_quality_1_10")

lifestyle_plots <- lapply(lifestyle_vars, function(var) {
  plot_lifestyle_vs_severity(anxiety_data_processed, var)
})



# --- Age Groups vs. Anxiety Severity (within high-stress/high-severity) ---
anxiety_data_processed <- anxiety_data_processed %>%
  mutate(age_group = cut(age, breaks = c(18, 30, 45, 65), labels = c("18-29", "30-44", "45-64"), include.lowest = TRUE))

plot_age_severity <- ggplot(anxiety_data_processed %>% filter(high_stress == 1, high_severity == 1), aes(x = age_group, y = severity_of_anxiety_attack_1_10)) +
  geom_boxplot() +
  labs(title = "Anxiety Severity by Age Group (High Stress/Severity)",
       x = "Age Group",
       y = "Severity of Anxiety Attack (1-10)")
print(plot_age_severity)

# --- Histograms of Key Metrics, Faceted by high_stress and high_severity ---

# Heart Rate
plot_hr_facet <- ggplot(anxiety_data_processed, aes(x = heart_rate_bpm_during_attack)) +
  geom_histogram(bins = 30) +
  facet_grid(high_stress ~ high_severity) +
  labs(title = "Heart Rate Distribution by Stress and Severity",
       x = "Heart Rate (bpm)",
       y = "Count")
print(plot_hr_facet)


# Breathing Rate
plot_br_facet <- ggplot(anxiety_data_processed, aes(x = breathing_rate_breaths_min)) +
  geom_histogram(bins = 30) +
  facet_grid(high_stress ~ high_severity) +
  labs(title = "Breathing Rate Distribution by Stress and Severity",
       x = "Breathing Rate (breaths/min)",
       y = "Count")
print(plot_br_facet)


# --- Stacked Bar Plots for Categorical Variables (Question 6) ---
plot_categorical_comparison <- function(data, var_name) {
    plot <- ggplot(data, aes(x = factor(severity_of_anxiety_attack_1_10), fill = .data[[var_name]] )) +
        geom_bar(position = "fill") +
        labs(title = paste("Proportion of", var_name, "by Anxiety Severity"),
        x = "Severity of Anxiety Attack (1-10)",
        y = "Proportion",
        fill = var_name) +
        scale_y_continuous(labels = scales::percent)
    if (capture_all_output) { # Only print if capture_all_output is TRUE
        print(plot)
    }
    return(plot)
}

categorical_vars_q6 <- c("smoking", "family_history_of_anxiety", "dizziness", "recent_major_life_event")

categorical_comparison_plots <- lapply(categorical_vars_q6, function(var){
    plot_categorical_comparison(anxiety_data_processed, var)
})


# Combine and save plots
all_plots <- c(list(plot_stress_severity, plot_untreated_severity),
               lifestyle_plots,
               list(plot_age_severity, plot_hr_facet, plot_br_facet),
               categorical_comparison_plots)

combine_and_save(all_plots, file.path(plots_folder, "combined_analysis_plots.png"), ncol = 3, type = "other")
Error in `wrap_plots()`:
! Only know how to add <ggplot> and/or <grob> objects
Backtrace:
 1. global combine_and_save(...)
 2. patchwork::wrap_plots(histograms, ncol = ncol, guides = "collect")

6.3. Correlation Analysis

6.4. Statistical Tests (Optional)

6.5. Modeling (Optional)

6.6 Enhancements

6.7 Analysis Summary and Findings

Add a section to summarize all the findings from the different analysis and tie it with the questions defined in the Ask phase.

LS0tDQp0aXRsZTogIkFueGlldHkgU3VwcG9ydCBBcHA6IERhdGEgUHJlcGFyYXRpb24gYW5kIFByb2Nlc3NpbmciDQphdXRob3I6ICJZb3VyIE5hbWUgLSBEYXRhIEFuYWx5c3QgQ2FuZGlkYXRlIg0KZGF0ZTogIk9jdG9iZXIgMjYsIDIwMjMiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2sNCi0tLQ0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpjYXB0dXJlX2FsbF9vdXRwdXQgPC0gVFJVRSAgIyBTZXQgdG8gRkFMU0UgZm9yIGludGVyYWN0aXZlIHVzZQ0KDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc2tpbXIpDQpsaWJyYXJ5KGhlcmUpDQpsaWJyYXJ5KGphbml0b3IpDQpsaWJyYXJ5KHBhdGNod29yaykNCg0KIyBEZWZpbmUgb3V0cHV0IGZpbGUgcGF0aA0KcHJvamVjdF9yb290IDwtIGhlcmUoKQ0KZGF0YV9mb2xkZXIgPC0gZmlsZS5wYXRoKHByb2plY3Rfcm9vdCwgImRhdGEiKQ0Kb3V0cHV0X2ZvbGRlciA8LSBmaWxlLnBhdGgocHJvamVjdF9yb290LCAib3V0cHV0IikNCnBsb3RzX2ZvbGRlciA8LSBmaWxlLnBhdGgob3V0cHV0X2ZvbGRlciwgInBsb3RzIikNCg0KIyBDcmVhdGUgb3V0cHV0IGRpcmVjdG9yaWVzDQppZiAoIWRpci5leGlzdHMob3V0cHV0X2ZvbGRlcikpIHsNCiAgZGlyLmNyZWF0ZShvdXRwdXRfZm9sZGVyKQ0KfQ0KaWYgKCFkaXIuZXhpc3RzKHBsb3RzX2ZvbGRlcikpIHsNCiAgZGlyLmNyZWF0ZShwbG90c19mb2xkZXIpDQp9DQoNCm91dHB1dF9maWxlX3BhdGggPC0gZmlsZS5wYXRoKG91dHB1dF9mb2xkZXIsICJkYXRhX3ByZXBfcHJvY2Vzc19sb2cudHh0IikgI1VwZGF0ZWQNCmRhdGFfZmlsZV9wYXRoIDwtIGZpbGUucGF0aChkYXRhX2ZvbGRlciwgImFueGlldHlfYXR0YWNrX2RhdGFzZXQuY3N2IikNCmBgYA0KDQojIyAxLiBJbnRyb2R1Y3Rpb24NCg0KVGhpcyByZXBvcnQgZG9jdW1lbnRzIHRoZSBkYXRhIHByZXBhcmF0aW9uIGFuZCBwcm9jZXNzaW5nIHN0ZXBzIGZvciB0aGUgIkFueGlldHkgU3VwcG9ydCBBcHA6IE1hcmtldGluZyBBdWRpZW5jZSBJZGVudGlmaWNhdGlvbiIgY2FzZSBzdHVkeS4gIFRoZSBwcmltYXJ5IG9iamVjdGl2ZSBpcyB0byBpZGVudGlmeSBhbmQgY2hhcmFjdGVyaXplIHBvdGVudGlhbCB0YXJnZXQgYXVkaWVuY2VzIGZvciB0aGUgIkNhbG0gQnV0dG9uIiBhcHBsaWNhdGlvbi4NCg0KIyMgMi4gUHJvamVjdCBTZXR1cCBhbmQgRGF0YSBBY3F1aXNpdGlvbg0KDQojIyMgMi4xIExvYWRpbmcgTmVjZXNzYXJ5IExpYnJhcmllcw0KDQooTGlicmFyaWVzIGFyZSBsb2FkZWQgaW4gdGhlIHNldHVwIGNodW5rKQ0KDQojIyMgMi4yIERlZmluaW5nIFByb2plY3QgUGF0aHMNCg0KKFBhdGhzIGFyZSBkZWZpbmVkIGluIHRoZSBzZXR1cCBjaHVuaykNCg0KIyMjIDIuMyBJbXBvcnRpbmcgdGhlIERhdGFzZXQNCg0KYGBge3IgaW1wb3J0LWRhdGF9DQppZiAoY2FwdHVyZV9hbGxfb3V0cHV0KSB7DQogIHNpbmsoZmlsZSA9IG91dHB1dF9maWxlX3BhdGgsIGFwcGVuZCA9IFRSVUUsIHNwbGl0ID0gVFJVRSkNCiAgY2F0KCJcblxuLS0tIEltcG9ydGluZyBEYXRhIC0tLVxuXG4iKQ0KfQ0KDQphbnhpZXR5X2RhdGFfcmF3IDwtIHJlYWRfY3N2KGRhdGFfZmlsZV9wYXRoKQ0KDQppZiAoY2FwdHVyZV9hbGxfb3V0cHV0KSB7DQogIHByaW50KFN5cy50aW1lKCkpDQogIHNpbmsoKQ0KfQ0KYGBgDQoNCiMjIDMuIERldGFpbGVkIERhdGEgSW5zcGVjdGlvbiAoUHJlcGFyZSBQaGFzZSkNCg0KIyMjIDMuMSBJbXBvcnQgY2hlY2sNCg0KYGBge3IgaW1wb3J0LWNoZWNrfQ0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBzaW5rKGZpbGUgPSBvdXRwdXRfZmlsZV9wYXRoLCBhcHBlbmQgPSBUUlVFLCBzcGxpdCA9IFRSVUUpDQogIGNhdCgiXG5cbi0tLSBJbXBvcnQgQ2hlY2sgLS0tXG5cbiIpDQp9DQoNCmhlYWQoYW54aWV0eV9kYXRhX3JhdykNCg0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBwcmludChTeXMudGltZSgpKQ0KICBzaW5rKCkNCn0NCmBgYA0KDQojIyMgMy4yIENvbHVtbiBOYW1lIENsZWFuaW5nDQoNCmBgYHtyIGNsZWFuLW5hbWVzfQ0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBzaW5rKGZpbGUgPSBvdXRwdXRfZmlsZV9wYXRoLCBhcHBlbmQgPSBUUlVFLCBzcGxpdCA9IFRSVUUpDQogIGNhdCgiXG5cbi0tLSBDb2x1bW4gTmFtZSBDbGVhbmluZyAtLS1cblxuIikNCn0NCg0KYW54aWV0eV9kYXRhX2NsZWFuX25hbWVzIDwtIGphbml0b3I6OmNsZWFuX25hbWVzKGFueGlldHlfZGF0YV9yYXcpDQoNCmlmIChjYXB0dXJlX2FsbF9vdXRwdXQpIHsNCiAgICBwcmludChTeXMudGltZSgpKQ0KICBzaW5rKCkNCn0NCmBgYA0KDQojIyMgMy4zIERhdGEgU3RydWN0dXJlDQoNCmBgYHtyIGRhdGEtc3RydWN0dXJlfQ0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBzaW5rKGZpbGUgPSBvdXRwdXRfZmlsZV9wYXRoLCBhcHBlbmQgPSBUUlVFLCBzcGxpdCA9IFRSVUUpDQogIGNhdCgiXG5cbi0tLSBEYXRhIFN0cnVjdHVyZSAtLS1cblxuIikNCn0NCg0Kc3RyKGFueGlldHlfZGF0YV9jbGVhbl9uYW1lcykNCg0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICAgIHByaW50KFN5cy50aW1lKCkpDQogIHNpbmsoKQ0KfQ0KYGBgDQoNCiMjIyAzLjQgRGF0YSBEaXN0cmlidXRpb24NCg0KYGBge3IgZGF0YS1zdW1tYXJ5fQ0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBzaW5rKGZpbGUgPSBvdXRwdXRfZmlsZV9wYXRoLCBhcHBlbmQgPSBUUlVFLCBzcGxpdCA9IFRSVUUpDQogIGNhdCgiXG5cbi0tLSBEYXRhIFN1bW1hcnkgLS0tXG5cbiIpDQp9DQoNCnN1bW1hcnkoYW54aWV0eV9kYXRhX2NsZWFuX25hbWVzKQ0KDQppZiAoY2FwdHVyZV9hbGxfb3V0cHV0KSB7DQogICAgcHJpbnQoU3lzLnRpbWUoKSkNCiAgc2luaygpDQp9DQpgYGANCg0KIyMjIDMuNSBGdXJ0aGVyIERldGFpbHMNCg0KYGBge3IgZGF0YS1za2ltfQ0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBzaW5rKGZpbGUgPSBvdXRwdXRfZmlsZV9wYXRoLCBhcHBlbmQgPSBUUlVFLCBzcGxpdCA9IFRSVUUpDQogIGNhdCgiXG5cbi0tLSBEZXRhaWxlZCBEYXRhIFN1bW1hcnkgKHNraW1yKSAtLS1cblxuIikNCn0NCg0Kc2tpbShhbnhpZXR5X2RhdGFfY2xlYW5fbmFtZXMpDQoNCmlmIChjYXB0dXJlX2FsbF9vdXRwdXQpIHsNCiAgICBwcmludChTeXMudGltZSgpKQ0KICBzaW5rKCkNCn0NCmBgYA0KDQojIyA0LiBEZXRhaWxlZCBWYXJpYWJsZSBFeGFtaW5hdGlvbiAoUHJlcGFyZSBQaGFzZSBWaXN1YWxpemF0aW9ucykNCg0KYGBge3IgZnVuY3Rpb25zLCBpbmNsdWRlPUZBTFNFfQ0KIyAtLS0gRnVuY3Rpb24gZm9yIENhdGVnb3JpY2FsIFZhcmlhYmxlIFZpc3VhbGl6YXRpb24gLS0tDQpwbG90X2NhdGVnb3JpY2FsIDwtIGZ1bmN0aW9uKGRhdGEsIHZhcl9uYW1lKSB7DQogICMgQ3JlYXRlIGZyZXF1ZW5jeSB0YWJsZQ0KICBmcmVxX3RhYmxlIDwtIHRhYmxlKGRhdGFbW3Zhcl9uYW1lXV0pDQoNCiAgIyBDcmVhdGUgYmFyIHBsb3QNCiAgcGxvdCA8LSBnZ3Bsb3QoZGF0YSwgYWVzKHggPSAuZGF0YVtbdmFyX25hbWVdXSkpICsNCiAgICBnZW9tX2JhcigpICsNCiAgICBsYWJzKHRpdGxlID0gcGFzdGUoIkRpc3RyaWJ1dGlvbiBvZiIsIHZhcl9uYW1lKSwNCiAgICAgICAgIHggPSB2YXJfbmFtZSwNCiAgICAgICAgIHkgPSAiQ291bnQiKSArDQogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KICAjIFByaW50IHRvIGNvbnNvbGUgKGlmIGNhcHR1cmVfYWxsX291dHB1dCBpcyBUUlVFIGFuZCBzaW5rIGlzIGFjdGl2ZSkNCiAgaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICAgIHByaW50KHBhc3RlKCJGcmVxdWVuY3kgVGFibGUgZm9yIiwgdmFyX25hbWUsICI6IikpDQogICAgcHJpbnQoZnJlcV90YWJsZSkNCiAgICBwcmludChwbG90KQ0KICB9DQoNCg0KICByZXR1cm4obGlzdChwbG90ID0gcGxvdCwgZnJlcV90YWJsZSA9IGZyZXFfdGFibGUpKSAjIFJldHVybiBwbG90IGFuZCB0YWJsZQ0KfQ0KDQojIC0tLSBGdW5jdGlvbiBmb3IgTnVtZXJpYyBWYXJpYWJsZSBWaXN1YWxpemF0aW9uIC0tLQ0KcGxvdF9udW1lcmljIDwtIGZ1bmN0aW9uKGRhdGEsIHZhcl9uYW1lKSB7DQogICMgQ3JlYXRlIGhpc3RvZ3JhbQ0KICBwbG90X2hpc3QgPC0gZ2dwbG90KGRhdGEsIGFlcyh4ID0gLmRhdGFbW3Zhcl9uYW1lXV0pKSArDQogICAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDMwKSArICAjIEFkanVzdCBiaW5zIGFzIG5lZWRlZA0KICAgIGxhYnModGl0bGUgPSBwYXN0ZSgiRGlzdHJpYnV0aW9uIG9mIiwgdmFyX25hbWUpLA0KICAgICAgICAgeCA9IHZhcl9uYW1lLA0KICAgICAgICAgeSA9ICJDb3VudCIpDQoNCiAgIyBDcmVhdGUgYm94cGxvdA0KICBwbG90X2JveCA8LSBnZ3Bsb3QoZGF0YSwgYWVzKHkgPSAuZGF0YVtbdmFyX25hbWVdXSkpICsNCiAgICBnZW9tX2JveHBsb3QoKSArDQogICAgbGFicyh0aXRsZSA9IHBhc3RlKCJCb3hwbG90IG9mIiwgdmFyX25hbWUpLA0KICAgICAgICAgeSA9IHZhcl9uYW1lKQ0KDQogICMgUHJpbnQgdG8gY29uc29sZQ0KICBpZiAoY2FwdHVyZV9hbGxfb3V0cHV0KSB7DQogICAgcHJpbnQocGFzdGUoIkhpc3RvZ3JhbSBmb3IiLCB2YXJfbmFtZSkpDQogICAgcHJpbnQocGxvdF9oaXN0KQ0KICAgIHByaW50KHBhc3RlKCJCb3hwbG90IGZvciIsIHZhcl9uYW1lKSkNCiAgICBwcmludChwbG90X2JveCkNCiAgfQ0KDQogIHJldHVybihsaXN0KGhpc3RvZ3JhbSA9IHBsb3RfaGlzdCwgYm94cGxvdCA9IHBsb3RfYm94KSkNCn0NCg0KIyAtLS0gRnVuY3Rpb24gdG8gQ29tYmluZSBhbmQgU2F2ZSBQbG90cyAtLS0NCmNvbWJpbmVfYW5kX3NhdmUgPC0gZnVuY3Rpb24ocGxvdF9saXN0LCBmaWxlbmFtZSwgbmNvbCA9IDIsIHR5cGUgPSAiY2F0ZWdvcmljYWwiKSB7DQogIGlmICh0eXBlID09ICJjYXRlZ29yaWNhbCIpIHsNCiAgICBjb21iaW5lZF9wbG90IDwtIHdyYXBfcGxvdHMocGxvdF9saXN0LCBuY29sID0gbmNvbCwgZ3VpZGVzID0gImNvbGxlY3QiKQ0KDQogIH0gZWxzZSB7DQogICAgIyBFeHRyYWN0IGhpc3RvZ3JhbXMgYW5kIGJveHBsb3RzDQogICAgaGlzdG9ncmFtcyA8LSBsYXBwbHkocGxvdF9saXN0LCBmdW5jdGlvbih4KSB4JGhpc3RvZ3JhbSkNCiAgICBib3hwbG90cyA8LSBsYXBwbHkocGxvdF9saXN0LCBmdW5jdGlvbih4KSB4JGJveHBsb3QpDQoNCiAgICAjIENvbWJpbmUgaGlzdG9ncmFtcyBhbmQgYm94cGxvdHMgc2VwYXJhdGVseQ0KICAgIGNvbWJpbmVkX2hpc3RvZ3JhbXMgPC0gd3JhcF9wbG90cyhoaXN0b2dyYW1zLCBuY29sID0gbmNvbCwgZ3VpZGVzID0gImNvbGxlY3QiKQ0KICAgIGNvbWJpbmVkX2JveHBsb3RzIDwtIHdyYXBfcGxvdHMoYm94cGxvdHMsIG5jb2wgPSBuY29sLCBndWlkZXMgPSAiY29sbGVjdCIpDQoNCiAgICAjIENvbWJpbmUgYm90aCBzZXRzIG9mIHBsb3RzIChoaXN0b2dyYW1zIGFib3ZlIGJveHBsb3RzKQ0KICAgIGNvbWJpbmVkX3Bsb3QgPC0gY29tYmluZWRfaGlzdG9ncmFtcyAvIGNvbWJpbmVkX2JveHBsb3RzICMgVmVydGljYWwgYXJyYW5nZW1lbnQNCiAgfQ0KDQogIGdnc2F2ZShmaWxlbmFtZSwgY29tYmluZWRfcGxvdCwgd2lkdGggPSAxMiwgaGVpZ2h0ID0gOCAqIChsZW5ndGgocGxvdF9saXN0KSAvIDIpLCBkcGkgPSAzMDApICNBZGp1c3QgaGVpZ2h0DQp9DQoNCmBgYA0KDQojIyMgNC4xIENhdGVnb3JpY2FsIFZhcmlhYmxlIEFuYWx5c2lzDQoNCmBgYHtyIGNhdGVnb3JpY2FsLXBsb3RzfQ0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBzaW5rKGZpbGUgPSBvdXRwdXRfZmlsZV9wYXRoLCBhcHBlbmQgPSBUUlVFLCBzcGxpdCA9IFRSVUUpDQogIGNhdCgiXG5cbi0tLSBDYXRlZ29yaWNhbCBWYXJpYWJsZSBQbG90cyAtLS1cblxuIikNCn0NCg0KY2F0ZWdvcmljYWxfdmFycyA8LSBjKCJnZW5kZXIiLCAib2NjdXBhdGlvbiIsICJzbW9raW5nIiwgImZhbWlseV9oaXN0b3J5X29mX2FueGlldHkiLA0KICAgICAgICAgICAgICAgICAgICAgImRpenppbmVzcyIsICJtZWRpY2F0aW9uIiwgInJlY2VudF9tYWpvcl9saWZlX2V2ZW50IikNCg0KIyBHZW5lcmF0ZSBwbG90cyBhbmQgdGFibGVzLCBzdG9yaW5nIHRoZW0gaW4gYSBsaXN0DQpjYXRlZ29yaWNhbF9yZXN1bHRzIDwtIGxhcHBseShjYXRlZ29yaWNhbF92YXJzLCBmdW5jdGlvbih2YXIpIHsNCiAgcGxvdF9jYXRlZ29yaWNhbChhbnhpZXR5X2RhdGFfY2xlYW5fbmFtZXMsIHZhcikNCn0pDQoNCiMgRXh0cmFjdCBqdXN0IHRoZSBwbG90cyBmb3IgY29tYmluaW5nDQpjYXRlZ29yaWNhbF9wbG90cyA8LSBsYXBwbHkoY2F0ZWdvcmljYWxfcmVzdWx0cywgZnVuY3Rpb24oeCkgeCRwbG90KQ0KDQojIENvbWJpbmUgYW5kIHNhdmUNCmNvbWJpbmVfYW5kX3NhdmUoY2F0ZWdvcmljYWxfcGxvdHMsIGZpbGUucGF0aChwbG90c19mb2xkZXIsICJjb21iaW5lZF9jYXRlZ29yaWNhbF9wbG90cy5wbmciKSwgdHlwZSA9ICJjYXRlZ29yaWNhbCIpDQoNCg0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICAgIHByaW50KFN5cy50aW1lKCkpDQogIHNpbmsoKQ0KfQ0KYGBgDQoNCiMjIyA0LjIgTnVtZXJpYyBWYXJpYWJsZSBBbmFseXNpcw0KDQpgYGB7ciBudW1lcmljLXBsb3RzfQ0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBzaW5rKGZpbGUgPSBvdXRwdXRfZmlsZV9wYXRoLCBhcHBlbmQgPSBUUlVFLCBzcGxpdCA9IFRSVUUpDQogIGNhdCgiXG5cbi0tLSBOdW1lcmljIFZhcmlhYmxlIFBsb3RzIC0tLVxuXG4iKQ0KfQ0KDQpudW1lcmljX3ZhcnMgPC0gYygiYWdlIiwgInNsZWVwX2hvdXJzIiwgInBoeXNpY2FsX2FjdGl2aXR5X2hyc193ZWVrIiwNCiAgICAgICAgICAgICAgICAgImNhZmZlaW5lX2ludGFrZV9tZ19kYXkiLCAiYWxjb2hvbF9jb25zdW1wdGlvbl9kcmlua3Nfd2VlayIsDQogICAgICAgICAgICAgICAgICJzdHJlc3NfbGV2ZWxfMV8xMCIsICJoZWFydF9yYXRlX2JwbV9kdXJpbmdfYXR0YWNrIiwNCiAgICAgICAgICAgICAgICAgImJyZWF0aGluZ19yYXRlX2JyZWF0aHNfbWluIiwgInN3ZWF0aW5nX2xldmVsXzFfNSIsDQogICAgICAgICAgICAgICAgICJ0aGVyYXB5X3Nlc3Npb25zX3Blcl9tb250aCIsICJkaWV0X3F1YWxpdHlfMV8xMCIsDQogICAgICAgICAgICAgICAgICJzZXZlcml0eV9vZl9hbnhpZXR5X2F0dGFja18xXzEwIikNCg0KIyBHZW5lcmF0ZSBwbG90cywgc3RvcmluZyB0aGVtIGluIGEgbGlzdA0KbnVtZXJpY19yZXN1bHRzIDwtIGxhcHBseShudW1lcmljX3ZhcnMsIGZ1bmN0aW9uKHZhcikgew0KICBwbG90X251bWVyaWMoYW54aWV0eV9kYXRhX2NsZWFuX25hbWVzLCB2YXIpDQp9KQ0KDQojIENvbWJpbmUgYW5kIHNhdmUgbnVtZXJpYyBwbG90cyAoaGlzdG9ncmFtcyBhbmQgYm94cGxvdHMpDQpjb21iaW5lX2FuZF9zYXZlKG51bWVyaWNfcmVzdWx0cywgZmlsZS5wYXRoKHBsb3RzX2ZvbGRlciwgImNvbWJpbmVkX251bWVyaWNfcGxvdHMucG5nIiksIHR5cGUgPSAibnVtZXJpYyIpDQoNCg0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBwcmludChTeXMudGltZSgpKQ0KICBzaW5rKCkNCn0NCmBgYA0KDQojIyMgNC4zIERhdGEgVHlwZSBDb252ZXJzaW9uIFBsYW4NCg0KVGhlIGZvbGxvd2luZyB2YXJpYWJsZXMgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gZmFjdG9ycyBpbiB0aGUgUHJvY2VzcyBwaGFzZToNCg0KKiAgICoqZ2VuZGVyOioqIENhdGVnb3JpY2FsIHZhcmlhYmxlLg0KKiAgICoqb2NjdXBhdGlvbjoqKiBDYXRlZ29yaWNhbCB2YXJpYWJsZS4NCiogICAqKnNtb2tpbmc6KiogQ2F0ZWdvcmljYWwgKFllcy9ObykuDQoqICAgKipmYW1pbHlfaGlzdG9yeV9vZl9hbnhpZXR5OioqIENhdGVnb3JpY2FsIChZZXMvTm8pLg0KKiAgICoqZGl6emluZXNzOioqIENhdGVnb3JpY2FsIChZZXMvTm8pLg0KKiAgICoqbWVkaWNhdGlvbjoqKiBDYXRlZ29yaWNhbCAoWWVzL05vKS4NCiogICAqKnJlY2VudF9tYWpvcl9saWZlX2V2ZW50OioqIENhdGVnb3JpY2FsIChZZXMvTm8pLg0KDQojIyMgNC40IER1cGxpY2F0ZSBDaGVjaw0KDQpgYGB7ciBkdXBsaWNhdGUtY2hlY2t9DQppZiAoY2FwdHVyZV9hbGxfb3V0cHV0KSB7DQogIHNpbmsoZmlsZSA9IG91dHB1dF9maWxlX3BhdGgsIGFwcGVuZCA9IFRSVUUsIHNwbGl0ID0gVFJVRSkNCiAgY2F0KCJcblxuLS0tIER1cGxpY2F0ZSBDaGVjayAtLS1cblxuIikNCn0NCg0KZHVwbGljYXRlczwtIGFueGlldHlfZGF0YV9jbGVhbl9uYW1lcyAlPiUNCiAgZHVwbGljYXRlZCgpICU+JQ0KICBzdW0oKQ0KcHJpbnQoIk51bWJlciBvZiBEdXBsaWNhdGUgUm93czoiKQ0KcHJpbnQoZHVwbGljYXRlcykNCg0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICAgIHByaW50KFN5cy50aW1lKCkpDQogIHNpbmsoKQ0KfQ0KYGBgDQoNCiMjIyA0LjUgRXhwbGljaXQgTWlzc2luZyBWYWx1ZSBDaGVjaw0KDQpgYGB7ciBtaXNzaW5nLXZhbHVlLWNoZWNrfQ0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBzaW5rKGZpbGUgPSBvdXRwdXRfZmlsZV9wYXRoLCBhcHBlbmQgPSBUUlVFLCBzcGxpdCA9IFRSVUUpDQogIGNhdCgiXG5cbi0tLSBFeHBsaWNpdCBNaXNzaW5nIFZhbHVlIENoZWNrIC0tLVxuXG4iKQ0KfQ0KDQptaXNzaW5nX3ZhbHVlcyA8LSBjb2xTdW1zKGlzLm5hKGFueGlldHlfZGF0YV9jbGVhbl9uYW1lcykpDQpwcmludCgiTWlzc2luZyBWYWx1ZXMgcGVyIENvbHVtbjoiKQ0KcHJpbnQobWlzc2luZ192YWx1ZXMpDQoNCm1pc3NpbmdfcGVyY2VudGFnZXMgPC0gY29sTWVhbnMoaXMubmEoYW54aWV0eV9kYXRhX2NsZWFuX25hbWVzKSkgKiAxMDANCnByaW50KCJQZXJjZW50YWdlIG9mIE1pc3NpbmcgVmFsdWVzIHBlciBDb2x1bW46IikNCnByaW50KG1pc3NpbmdfcGVyY2VudGFnZXMpDQoNCg0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBwcmludChTeXMudGltZSgpKQ0KICBzaW5rKCkNCn0NCmBgYA0KDQojIyA1LiBEYXRhIFByb2Nlc3NpbmcgKFByb2Nlc3MgUGhhc2UpDQoNClRoaXMgc2VjdGlvbiBkZXRhaWxzIHRoZSBkYXRhIGNsZWFuaW5nIGFuZCB0cmFuc2Zvcm1hdGlvbiBzdGVwcywgYWRkcmVzc2luZyB0aGUgaXNzdWVzIGFuZCBwbGFucyBpZGVudGlmaWVkIGluIHRoZSBQcmVwYXJlIHBoYXNlLg0KDQojIyMgNS4xIERhdGEgVHlwZSBDb252ZXJzaW9uDQoNCmBgYHtyIGRhdGEtdHlwZS1jb252ZXJzaW9ufQ0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBzaW5rKGZpbGUgPSBvdXRwdXRfZmlsZV9wYXRoLCBhcHBlbmQgPSBUUlVFLCBzcGxpdCA9IFRSVUUpDQogIGNhdCgiXG5cbi0tLSBEYXRhIFR5cGUgQ29udmVyc2lvbiAtLS1cblxuIikNCn0NCg0KIyBDcmVhdGUgYSBjb3B5IGZvciBwcm9jZXNzaW5nDQphbnhpZXR5X2RhdGFfcHJvY2Vzc2VkIDwtIGFueGlldHlfZGF0YV9jbGVhbl9uYW1lcw0KDQojIENvbnZlcnQgY2hhcmFjdGVyIHZhcmlhYmxlcyB0byBmYWN0b3JzDQpjYXRlZ29yaWNhbF92YXJzIDwtIGMoImdlbmRlciIsICJvY2N1cGF0aW9uIiwgInNtb2tpbmciLCAiZmFtaWx5X2hpc3Rvcnlfb2ZfYW54aWV0eSIsDQogICAgICAgICAgICAgICAgICAgICAiZGl6emluZXNzIiwgIm1lZGljYXRpb24iLCAicmVjZW50X21ham9yX2xpZmVfZXZlbnQiKQ0KDQphbnhpZXR5X2RhdGFfcHJvY2Vzc2VkIDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lDQogIG11dGF0ZShhY3Jvc3MoYWxsX29mKGNhdGVnb3JpY2FsX3ZhcnMpLCBhcy5mYWN0b3IpKQ0KDQojIFZlcmlmeSBjb252ZXJzaW9uDQpzdHIoYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCkNCg0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBwcmludChTeXMudGltZSgpKQ0KICBzaW5rKCkNCn0NCmBgYA0KDQojIyMgNS4yIE91dGxpZXIgSW52ZXN0aWdhdGlvbiBhbmQgSGFuZGxpbmcNCg0KYGBge3Igb3V0bGllci1oYW5kbGluZ30NCmlmIChjYXB0dXJlX2FsbF9vdXRwdXQpIHsNCiAgc2luayhmaWxlID0gb3V0cHV0X2ZpbGVfcGF0aCwgYXBwZW5kID0gVFJVRSwgc3BsaXQgPSBUUlVFKQ0KICBjYXQoIlxuXG4tLS0gT3V0bGllciBJbnZlc3RpZ2F0aW9uIGFuZCBIYW5kbGluZyAtLS1cblxuIikNCn0NCg0KIyAtLS0gc2xlZXBfaG91cnMgLS0tDQojIEludmVzdGlnYXRlIHZhbHVlcyA8IDQNCmxvd19zbGVlcCA8LSBhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkICU+JSBmaWx0ZXIoc2xlZXBfaG91cnMgPCA0KQ0KcHJpbnQoIk9ic2VydmF0aW9ucyB3aXRoIHNsZWVwX2hvdXJzIDwgNDoiKQ0KcHJpbnQobG93X3NsZWVwKQ0KIyBEZWNpc2lvbjogS2VlcC4gIFdoaWxlIGxvdywgdGhlc2UgdmFsdWVzIGFyZSBwbGF1c2libGUuDQoNCiMgLS0tIHBoeXNpY2FsX2FjdGl2aXR5X2hyc193ZWVrIC0tLQ0KIyBJbnZlc3RpZ2F0ZSB2YWx1ZXMgPiA5DQpoaWdoX2FjdGl2aXR5IDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lIGZpbHRlcihwaHlzaWNhbF9hY3Rpdml0eV9ocnNfd2VlayA+IDkpDQpwcmludCgiT2JzZXJ2YXRpb25zIHdpdGggcGh5c2ljYWxfYWN0aXZpdHlfaHJzX3dlZWsgPiA5OiIpDQpwcmludChoaWdoX2FjdGl2aXR5KQ0KIyBEZWNpc2lvbjogS2VlcC4gVGhlc2UgYXJlIGhpZ2ggYnV0IHBsYXVzaWJsZSB2YWx1ZXMuDQoNCiMgLS0tIGNhZmZlaW5lX2ludGFrZV9tZ19kYXkgLS0tDQojIEludmVzdGlnYXRlIHZhbHVlcyA+IDQwMA0KaGlnaF9jYWZmZWluZSA8LSBhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkICU+JSBmaWx0ZXIoY2FmZmVpbmVfaW50YWtlX21nX2RheSA+IDQwMCkNCnByaW50KCJPYnNlcnZhdGlvbnMgd2l0aCBjYWZmZWluZV9pbnRha2VfbWdfZGF5ID4gNDAwOiIpDQpwcmludChoaWdoX2NhZmZlaW5lKQ0KIyBEZWNpc2lvbjogS2VlcC4gVGhlc2UgYXJlIGhpZ2gsIGJ1dCBwbGF1c2libGUsIHZhbHVlcy4NCg0KIyAtLS0gYWxjb2hvbF9jb25zdW1wdGlvbl9kcmlua3Nfd2VlayAtLS0NCiMgSW52ZXN0aWdhdGUgdmFsdWVzID4gMTQNCmhpZ2hfYWxjb2hvbCA8LSBhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkICU+JSBmaWx0ZXIoYWxjb2hvbF9jb25zdW1wdGlvbl9kcmlua3Nfd2VlayA+IDE0KQ0KcHJpbnQoIk9ic2VydmF0aW9ucyB3aXRoIGFsY29ob2xfY29uc3VtcHRpb25fZHJpbmtzX3dlZWsgPiAxNDoiKQ0KcHJpbnQoaGlnaF9hbGNvaG9sKQ0KIyBEZWNpc2lvbjogS2VlcC4gV2hpbGUgYWJvdmUgcmVjb21tZW5kZWQgbGltaXRzLCB0aGV5IGFyZSBwbGF1c2libGUuDQoNCiMgLS0tIGhlYXJ0X3JhdGVfYnBtX2R1cmluZ19hdHRhY2sgLS0tDQojIEludmVzdGlnYXRlIHZhbHVlcyA8IDcwIGFuZCA+IDE2MA0KbG93X2hyIDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lIGZpbHRlcihoZWFydF9yYXRlX2JwbV9kdXJpbmdfYXR0YWNrIDwgNzApDQpwcmludCgiT2JzZXJ2YXRpb25zIHdpdGggaGVhcnRfcmF0ZV9icG1fZHVyaW5nX2F0dGFjayA8IDcwOiIpDQpwcmludChsb3dfaHIpDQoNCmhpZ2hfaHIgPC0gYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCAlPiUgZmlsdGVyKGhlYXJ0X3JhdGVfYnBtX2R1cmluZ19hdHRhY2sgPiAxNjApDQpwcmludCgiT2JzZXJ2YXRpb25zIHdpdGggaGVhcnRfcmF0ZV9icG1fZHVyaW5nX2F0dGFjayA+IDE2MDoiKQ0KcHJpbnQoaGlnaF9ocikNCiMgRGVjaXNpb246IEtlZXAuIEFmdGVyIHJldmlld2luZyB0aGUgY29udGV4dCwgdmFsdWVzIGFyZSBrZXB0Lg0KDQojIC0tLSBicmVhdGhpbmdfcmF0ZV9icmVhdGhzX21pbiAtLS0NCiMgSW52ZXN0aWdhdGUgdmFsdWVzIDwgMTUgYW5kID4gMzUNCmxvd19iciA8LSBhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkICU+JSBmaWx0ZXIoYnJlYXRoaW5nX3JhdGVfYnJlYXRoc19taW4gPCAxNSkNCnByaW50KCJPYnNlcnZhdGlvbnMgd2l0aCBicmVhdGhpbmdfcmF0ZV9icmVhdGhzX21pbiA8IDE1OiIpDQpwcmludChsb3dfYnIpDQpoaWdoX2JyIDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lIGZpbHRlcihicmVhdGhpbmdfcmF0ZV9icmVhdGhzX21pbiA+IDM1KQ0KcHJpbnQoIk9ic2VydmF0aW9ucyB3aXRoIGJyZWF0aGluZ19yYXRlX2JyZWF0aHNfbWluID4gMzU6IikNCnByaW50KGhpZ2hfYnIpDQojIERlY2lzaW9uOiBLZWVwLiBBZnRlciByZXZpZXdpbmcgdGhlIGNvbnRleHQsIHZhbHVlcyBhcmUga2VwdC4NCg0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBwcmludChTeXMudGltZSgpKQ0KICBzaW5rKCkNCn0NCmBgYA0KDQojIyMgNS4zLiBWYXJpYWJsZSBDcmVhdGlvbg0KDQpgYGB7ciB2YXJpYWJsZS1jcmVhdGlvbn0NCmlmIChjYXB0dXJlX2FsbF9vdXRwdXQpIHsNCiAgICBzaW5rKGZpbGUgPSBvdXRwdXRfZmlsZV9wYXRoLCBhcHBlbmQgPSBUUlVFLCBzcGxpdCA9IFRSVUUpDQogICAgY2F0KCJcblxuLS0tIFZhcmlhYmxlIENyZWF0aW9uIC0tLVxuXG4iKQ0KfQ0KDQojIC0tLSBIaWdoIFN0cmVzcyBJbmRpY2F0b3IgLS0tDQphbnhpZXR5X2RhdGFfcHJvY2Vzc2VkIDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lDQogIG11dGF0ZShoaWdoX3N0cmVzcyA9IGlmZWxzZShzdHJlc3NfbGV2ZWxfMV8xMCA+PSA4LCAxLCAwKSkNCg0KIyAtLS0gSGlnaCBTZXZlcml0eSBJbmRpY2F0b3IgLS0tDQphbnhpZXR5X2RhdGFfcHJvY2Vzc2VkIDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lDQogIG11dGF0ZShoaWdoX3NldmVyaXR5ID0gaWZlbHNlKHNldmVyaXR5X29mX2FueGlldHlfYXR0YWNrXzFfMTAgPj0gOCwgMSwgMCkpDQoNCiMgLS0tIFVudHJlYXRlZCBJbmRpY2F0b3IgLS0tDQphbnhpZXR5X2RhdGFfcHJvY2Vzc2VkIDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lDQogIG11dGF0ZSh1bnRyZWF0ZWQgPSBpZmVsc2UoaGlnaF9zdHJlc3MgPT0gMSAmIGhpZ2hfc2V2ZXJpdHkgPT0gMSAmIHRoZXJhcHlfc2Vzc2lvbnNfcGVyX21vbnRoID09IDAgJiBtZWRpY2F0aW9uID09ICJObyIsIDEsIDApKQ0KDQojIC0tLSBMb3cgU2xlZXAgSW5kaWNhdG9yIC0tLQ0KYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCA8LSBhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkICU+JQ0KICAgICAgbXV0YXRlKGxvd19zbGVlcCA9IGlmZWxzZShzbGVlcF9ob3VycyA8IDcsIDEsIDApKQ0KDQoNCiMgLS0tIEhpZ2ggQWxjb2hvbCBDb25zdW1wdGlvbiBJbmRpY2F0b3IgLS0tDQphbnhpZXR5X2RhdGFfcHJvY2Vzc2VkIDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lDQogICAgICBtdXRhdGUoaGlnaF9hbGNvaG9sID0gaWZlbHNlKCAoZ2VuZGVyID09ICJGZW1hbGUiICYgYWxjb2hvbF9jb25zdW1wdGlvbl9kcmlua3Nfd2VlayA+PSA4KSB8DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGdlbmRlciA9PSAiTWFsZSIgICAmIGFsY29ob2xfY29uc3VtcHRpb25fZHJpbmtzX3dlZWsgPj0gMTUpIHwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZ2VuZGVyID09ICJPdGhlciIgJiBhbGNvaG9sX2NvbnN1bXB0aW9uX2RyaW5rc193ZWVrID49IDE1KQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsIDEsIDApKQ0KDQojIC0tLSBIaWdoIENhZmZlaW5lIENvbnN1bXB0aW9uIEluZGljYXRvciAtLS0NCmFueGlldHlfZGF0YV9wcm9jZXNzZWQgPC0gYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCAlPiUNCiAgICBtdXRhdGUoaGlnaF9jYWZmZWluZSA9IGlmZWxzZShjYWZmZWluZV9pbnRha2VfbWdfZGF5ID4gNDAwLCAxLCAwKSkNCg0KI1ZlcmlmeQ0Kc3RyKGFueGlldHlfZGF0YV9wcm9jZXNzZWQpDQoNCmlmIChjYXB0dXJlX2FsbF9vdXRwdXQpIHsNCiAgcHJpbnQoU3lzLnRpbWUoKSkNCiAgc2luaygpDQp9DQpgYGANCg0KIyMjIDUuNC4gVmVyaWZpY2F0aW9uDQoNCmBgYHtyIHZlcmlmaWNhdGlvbn0NCiMgLS0tIFZlcmlmaWNhdGlvbiAtLS0NCmlmIChjYXB0dXJlX2FsbF9vdXRwdXQpIHsNCiAgc2luayhmaWxlID0gb3V0cHV0X2ZpbGVfcGF0aCwgYXBwZW5kID0gVFJVRSwgc3BsaXQgPSBUUlVFKQ0KICBjYXQoIlxuXG4tLS0gVmVyaWZpY2F0aW9uIC0tLVxuXG4iKQ0KfQ0KDQojIENoZWNrIGZvciBOQSdzIGFnYWluIGluIHRoZSBuZXcgdmFyaWFibGVzDQptaXNzaW5nX3ZhbHVlc19wcm9jZXNzZWQgPC0gY29sU3Vtcyhpcy5uYShhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkKSkNCnByaW50KCJNaXNzaW5nIFZhbHVlcyBwZXIgQ29sdW1uIEFmdGVyIFByb2Nlc3Npbmc6IikNCnByaW50KG1pc3NpbmdfdmFsdWVzX3Byb2Nlc3NlZCkNCg0KIyBDaGVjayBmb3IgRHVwbGljYXRlcyBhZ2Fpbg0KZHVwbGljYXRlc19wcm9jZXNzZWQgPC0gYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCAlPiUNCiAgZHVwbGljYXRlZCgpICU+JQ0KICBzdW0oKQ0KcHJpbnQoIk51bWJlciBvZiBEdXBsaWNhdGUgUm93cyBBZnRlciBQcm9jZXNzaW5nOiIpDQpwcmludChkdXBsaWNhdGVzX3Byb2Nlc3NlZCkNCg0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBwcmludChTeXMudGltZSgpKQ0KICBzaW5rKCkNCn0NCmBgYA0KDQojIyA2LiBEYXRhIEFuYWx5c2lzIChBbmFseXplIFBoYXNlKQ0KDQojIyMgNi4xLiBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzIChUYXJnZXRlZCBHcm91cHMpDQoNCmBgYHtyIGRlc2NyaXB0aXZlLXN0YXRzfQ0KIyAtLS0gRGVzY3JpcHRpdmUgU3RhdGlzdGljcyAoVGFyZ2V0ZWQgR3JvdXBzKSAtLS0NCmlmIChjYXB0dXJlX2FsbF9vdXRwdXQpIHsNCiAgc2luayhmaWxlID0gb3V0cHV0X2ZpbGVfcGF0aCwgYXBwZW5kID0gVFJVRSwgc3BsaXQgPSBUUlVFKQ0KICBjYXQoIlxuXG4tLS0gRGVzY3JpcHRpdmUgU3RhdGlzdGljcyAoVGFyZ2V0ZWQgR3JvdXBzKSAtLS1cblxuIikNCn0NCg0KbGlicmFyeShrbml0cikgIyBNYWtlIHN1cmUga25pdHIgaXMgbG9hZGVkDQoNCiMgLS0tIE92ZXJhbGwgRGVzY3JpcHRpdmUgU3RhdGlzdGljcyAtLS0NCmNhdCgiXG5PdmVyYWxsIERlc2NyaXB0aXZlIFN0YXRpc3RpY3M6XG4iKQ0KcHJpbnQoa2FibGUoc2tpbShhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkKSwgZm9ybWF0ID0gIm1hcmtkb3duIikpDQoNCg0KIyAtLS0gSGlnaCBTdHJlc3MgR3JvdXAgKHN0cmVzc19sZXZlbF8xXzEwID49IDgpIC0tLQ0KY2F0KCJcbkhpZ2ggU3RyZXNzIEdyb3VwIChzdHJlc3NfbGV2ZWxfMV8xMCA+PSA4KTpcbiIpDQpoaWdoX3N0cmVzc19za2ltIDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lDQogIGZpbHRlcihoaWdoX3N0cmVzcyA9PSAxKSAlPiUNCiAgc2tpbSgpDQpwcmludChrYWJsZShoaWdoX3N0cmVzc19za2ltLCBmb3JtYXQgPSAibWFya2Rvd24iKSkNCg0KIyAtLS0gSGlnaCBTZXZlcml0eSBHcm91cCAoc2V2ZXJpdHlfb2ZfYW54aWV0eV9hdHRhY2tfMV8xMCA+PSA4KSAtLS0NCmNhdCgiXG5IaWdoIFNldmVyaXR5IEdyb3VwIChzZXZlcml0eV9vZl9hbnhpZXR5X2F0dGFja18xXzEwID49IDgpOlxuIikNCmhpZ2hfc2V2ZXJpdHlfc2tpbSA8LSBhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkICU+JQ0KICBmaWx0ZXIoaGlnaF9zZXZlcml0eSA9PSAxKSAlPiUNCiAgc2tpbSgpDQpwcmludChrYWJsZShoaWdoX3NldmVyaXR5X3NraW0sIGZvcm1hdCA9ICJtYXJrZG93biIpKQ0KDQoNCiMgLS0tIFVudHJlYXRlZCBHcm91cCAoaGlnaF9zdHJlc3MsIGhpZ2hfc2V2ZXJpdHksIG5vIHRoZXJhcHkvbWVkaWNhdGlvbikgLS0tDQpjYXQoIlxuVW50cmVhdGVkIEdyb3VwIChIaWdoIFN0cmVzcywgSGlnaCBTZXZlcml0eSwgTm8gVGhlcmFweS9NZWRpY2F0aW9uKTpcbiIpDQp1bnRyZWF0ZWRfc2tpbSA8LSBhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkICU+JQ0KICBmaWx0ZXIodW50cmVhdGVkID09IDEpICU+JQ0KICBza2ltKCkNCnByaW50KGthYmxlKHVudHJlYXRlZF9za2ltLCBmb3JtYXQgPSAibWFya2Rvd24iKSkNCg0KDQojIC0tLSBMb3cgU2xlZXAgR3JvdXAgKHNsZWVwX2hvdXJzIDwgNykgLS0tDQpjYXQoIlxuTG93IFNsZWVwIEdyb3VwIChzbGVlcF9ob3VycyA8IDcpOlxuIikNCmxvd19zbGVlcF9za2ltIDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lDQogIGZpbHRlcihsb3dfc2xlZXAgPT0gMSkgJT4lDQogIHNraW0oKQ0KcHJpbnQoa2FibGUobG93X3NsZWVwX3NraW0sIGZvcm1hdCA9ICJtYXJrZG93biIpKQ0KDQojIC0tLSBIaWdoIEFsY29ob2wgR3JvdXAgLS0tDQpjYXQoIlxuSGlnaCBBbGNvaG9sIEdyb3VwOlxuIikNCmhpZ2hfYWxjb2hvbF9za2ltIDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lDQogIGZpbHRlcihoaWdoX2FsY29ob2wgPT0gMSkgJT4lDQogIHNraW0oKQ0KcHJpbnQoa2FibGUoaGlnaF9hbGNvaG9sX3NraW0sIGZvcm1hdCA9ICJtYXJrZG93biIpKQ0KDQoNCiMgLS0tIEhpZ2ggQ2FmZmVpbmUgR3JvdXAgLS0tDQpjYXQoIlxuSGlnaCBDYWZmZWluZSBHcm91cDpcbiIpDQpoaWdoX2NhZmZlaW5lX3NraW0gPC0gYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCAlPiUNCiAgZmlsdGVyKGhpZ2hfY2FmZmVpbmUgPT0gMSkgJT4lDQogIHNraW0oKQ0KcHJpbnQoa2FibGUoaGlnaF9jYWZmZWluZV9za2ltLCBmb3JtYXQgPSAibWFya2Rvd24iKSkNCg0KIyAtLS0gU3BlY2lmaWMgU3RhdGlzdGljcyBmb3IgS2V5IFF1ZXN0aW9ucyAtLS0NCiMgQ3JlYXRlIGEgZGF0YSBmcmFtZSB0byBzdG9yZSB0aGVzZSByZXN1bHRzDQprZXlfc3RhdHMgPC0gZGF0YS5mcmFtZSgNCiAgUXVlc3Rpb24gPSBjaGFyYWN0ZXIoKSwNCiAgU3RhdGlzdGljID0gY2hhcmFjdGVyKCksDQogIFZhbHVlID0gbnVtZXJpYygpLA0KICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UNCikNCg0KIyBRdWVzdGlvbiAxOiBQZXJjZW50YWdlIHdpdGggc2V2ZXJlIGFueGlldHkgYXR0YWNrcyBpbiBoaWdoLXN0cmVzcyBncm91cA0KDQpxMV9yZXN1bHQgPC0gYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCAlPiUNCiAgZmlsdGVyKGhpZ2hfc3RyZXNzID09IDEpICU+JQ0KICBzdW1tYXJpemUocGVyY2VudF9oaWdoX3NldmVyaXR5ID0gbWVhbihoaWdoX3NldmVyaXR5KSAqIDEwMCkNCmtleV9zdGF0cyA8LSByYmluZChrZXlfc3RhdHMsIGRhdGEuZnJhbWUoUXVlc3Rpb24gPSAiUTEiLCBTdGF0aXN0aWMgPSAiUGVyY2VudCBIaWdoIFNldmVyaXR5IChIaWdoIFN0cmVzcykiLCBWYWx1ZSA9IHExX3Jlc3VsdCRwZXJjZW50X2hpZ2hfc2V2ZXJpdHkpKQ0KDQoNCiMgUXVlc3Rpb24gMzogUHJvcG9ydGlvbiB1bnRyZWF0ZWQgaW4gaGlnaC1zdHJlc3MvaGlnaC1zZXZlcml0eSBncm91cA0KDQpxM19yZXN1bHQgPC0gYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCAlPiUNCiAgZmlsdGVyKGhpZ2hfc3RyZXNzID09IDEsIGhpZ2hfc2V2ZXJpdHkgPT0gMSkgJT4lDQogIHN1bW1hcml6ZShwcm9wb3J0aW9uX3VudHJlYXRlZCA9IG1lYW4odW50cmVhdGVkKSAqIDEwMCkNCmtleV9zdGF0cyA8LSByYmluZChrZXlfc3RhdHMsIGRhdGEuZnJhbWUoUXVlc3Rpb24gPSAiUTMiLCBTdGF0aXN0aWMgPSAiUGVyY2VudCBVbnRyZWF0ZWQgKEhpZ2ggU3RyZXNzL1NldmVyaXR5KSIsIFZhbHVlID0gcTNfcmVzdWx0JHByb3BvcnRpb25fdW50cmVhdGVkKSkNCg0KDQojIFF1ZXN0aW9uIDg6IGF2ZXJhZ2UgaGVhcnQgcmF0ZSBhbmQgYnJlYXRoaW5nIHJhdGUNCnE4X2hpZ2hfcmVzdWx0IDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lDQogICAgZmlsdGVyKHNldmVyaXR5X29mX2FueGlldHlfYXR0YWNrXzFfMTAgPj0gOCkgJT4lDQogICAgc3VtbWFyaXNlKGF2ZXJhZ2VfaGVhcnRfcmF0ZSA9IG1lYW4oaGVhcnRfcmF0ZV9icG1fZHVyaW5nX2F0dGFjayksDQogICAgICAgICAgICAgIGF2ZXJhZ2VfYnJlYXRoaW5nX3JhdGUgPSBtZWFuKGJyZWF0aGluZ19yYXRlX2JyZWF0aHNfbWluKSkNCmtleV9zdGF0cyA8LSByYmluZChrZXlfc3RhdHMsIGRhdGEuZnJhbWUoUXVlc3Rpb24gPSAiUTggKEhpZ2gpIiwgU3RhdGlzdGljID0gIkF2ZXJhZ2UgSGVhcnQgUmF0ZSIsIFZhbHVlID0gcThfaGlnaF9yZXN1bHQkYXZlcmFnZV9oZWFydF9yYXRlKSkNCmtleV9zdGF0cyA8LSByYmluZChrZXlfc3RhdHMsIGRhdGEuZnJhbWUoUXVlc3Rpb24gPSAiUTggKEhpZ2gpIiwgU3RhdGlzdGljID0gIkF2ZXJhZ2UgQnJlYXRoaW5nIFJhdGUiLCBWYWx1ZSA9IHE4X2hpZ2hfcmVzdWx0JGF2ZXJhZ2VfYnJlYXRoaW5nX3JhdGUpKQ0KDQoNCnE4X2xvd19yZXN1bHQgPC0gYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCAlPiUNCiAgICBmaWx0ZXIoc2V2ZXJpdHlfb2ZfYW54aWV0eV9hdHRhY2tfMV8xMCA8IDQpICU+JQ0KICAgIHN1bW1hcmlzZShhdmVyYWdlX2hlYXJ0X3JhdGUgPSBtZWFuKGhlYXJ0X3JhdGVfYnBtX2R1cmluZ19hdHRhY2spLA0KICAgICAgICAgICAgICBhdmVyYWdlX2JyZWF0aGluZ19yYXRlID0gbWVhbihicmVhdGhpbmdfcmF0ZV9icmVhdGhzX21pbikpDQprZXlfc3RhdHMgPC0gcmJpbmQoa2V5X3N0YXRzLCBkYXRhLmZyYW1lKFF1ZXN0aW9uID0gIlE4IChMb3cpIiwgU3RhdGlzdGljID0gIkF2ZXJhZ2UgSGVhcnQgUmF0ZSIsIFZhbHVlID0gcThfbG93X3Jlc3VsdCRhdmVyYWdlX2hlYXJ0X3JhdGUpKQ0Ka2V5X3N0YXRzIDwtIHJiaW5kKGtleV9zdGF0cywgZGF0YS5mcmFtZShRdWVzdGlvbiA9ICJROCAoTG93KSIsIFN0YXRpc3RpYyA9ICJBdmVyYWdlIEJyZWF0aGluZyBSYXRlIiwgVmFsdWUgPSBxOF9sb3dfcmVzdWx0JGF2ZXJhZ2VfYnJlYXRoaW5nX3JhdGUpKQ0KDQojIFF1ZXN0aW9uIDk6IG1lZGlhbiByZXBvcnRlZCBzZXZlcml0eV9vZl9hbnhpZXR5X2F0dGFja18xXzEwIG9mIHRob3NlIGluIHRoZXJhcHkNCnE5X3Jlc3VsdCA8LSBhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkICU+JQ0KICAgIGZpbHRlcih0aGVyYXB5X3Nlc3Npb25zX3Blcl9tb250aCA+IDApICU+JQ0KICAgIHN1bW1hcmlzZShtZWRpYW5fc2V2ZXJpdHlfd2l0aF90aGVyYXB5ID0gbWVkaWFuKHNldmVyaXR5X29mX2FueGlldHlfYXR0YWNrXzFfMTApKQ0Ka2V5X3N0YXRzIDwtIHJiaW5kKGtleV9zdGF0cywgZGF0YS5mcmFtZShRdWVzdGlvbiA9ICJROSIsIFN0YXRpc3RpYyA9ICJNZWRpYW4gU2V2ZXJpdHkgKFdpdGggVGhlcmFweSkiLCBWYWx1ZSA9IHE5X3Jlc3VsdCRtZWRpYW5fc2V2ZXJpdHlfd2l0aF90aGVyYXB5KSkNCg0KDQpjYXQoIlxuS2V5IFN0YXRpc3RpY3MgU3VtbWFyeTpcbiIpDQpwcmludChrYWJsZShrZXlfc3RhdHMsIGZvcm1hdCA9ICJtYXJrZG93biIpKQ0KDQoNCmlmIChjYXB0dXJlX2FsbF9vdXRwdXQpIHsNCiAgcHJpbnQoU3lzLnRpbWUoKSkNCiAgc2luaygpDQp9DQpgYGANCg0KIyMjIDYuMi4gVmlzdWFsaXphdGlvbnMNCg0KYGBge3IgdmlzdWFsaXphdGlvbnN9DQojIC0tLSBWaXN1YWxpemF0aW9ucyAtLS0NCmlmIChjYXB0dXJlX2FsbF9vdXRwdXQpIHsNCiAgc2luayhmaWxlID0gb3V0cHV0X2ZpbGVfcGF0aCwgYXBwZW5kID0gVFJVRSwgc3BsaXQgPSBUUlVFKQ0KICBjYXQoIlxuXG4tLS0gVmlzdWFsaXphdGlvbnMgLS0tXG5cbiIpDQp9DQoNCiMgLS0tIFN0cmVzcyBMZXZlbCB2cy4gQW54aWV0eSBTZXZlcml0eSAoQm94cGxvdCkgLS0tDQpwbG90X3N0cmVzc19zZXZlcml0eSA8LSBnZ3Bsb3QoYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCwgYWVzKHggPSBmYWN0b3IoaGlnaF9zdHJlc3MpLCB5ID0gc2V2ZXJpdHlfb2ZfYW54aWV0eV9hdHRhY2tfMV8xMCkpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBsYWJzKHRpdGxlID0gIkFueGlldHkgU2V2ZXJpdHkgYnkgSGlnaCBTdHJlc3MiLA0KICAgICAgIHggPSAiSGlnaCBTdHJlc3MgKDAgPSBObywgMSA9IFllcykiLA0KICAgICAgIHkgPSAiU2V2ZXJpdHkgb2YgQW54aWV0eSBBdHRhY2sgKDEtMTApIikNCiMgS2VlcCBwcmludCBzdGF0ZW1lbnQgZm9yIGNvbnNvbGUgb3V0cHV0DQpwcmludChwbG90X3N0cmVzc19zZXZlcml0eSkNCg0KIyAtLS0gVW50cmVhdGVkIHZzLiBUcmVhdGVkIChCb3hwbG90KSAtLS0NCnBsb3RfdW50cmVhdGVkX3NldmVyaXR5IDwtIGdncGxvdChhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkLCBhZXMoeCA9IGZhY3Rvcih1bnRyZWF0ZWQpLCB5ID0gc2V2ZXJpdHlfb2ZfYW54aWV0eV9hdHRhY2tfMV8xMCkpICsNCiAgICBnZW9tX2JveHBsb3QoKSArDQogICAgbGFicyh0aXRsZSA9ICJBbnhpZXR5IFNldmVyaXR5IGJ5IFVudHJlYXRlZCBTdGF0dXMiLA0KICAgICAgICAgeCA9ICJVbnRyZWF0ZWQgKDAgPSBObywgMSA9IFllcykiLA0KICAgICAgICAgeSA9ICJTZXZlcml0eSBvZiBBbnhpZXR5IEF0dGFjayAoMS0xMCkiKQ0KcHJpbnQocGxvdF91bnRyZWF0ZWRfc2V2ZXJpdHkpDQoNCiMgLS0tIExpZmVzdHlsZSBGYWN0b3JzIHZzLiBBbnhpZXR5IFNldmVyaXR5IChTY2F0dGVycGxvdHMpIC0tLQ0KDQpwbG90X2xpZmVzdHlsZV92c19zZXZlcml0eSA8LSBmdW5jdGlvbihkYXRhLCBsaWZlc3R5bGVfdmFyKSB7DQogIHBsb3QgPC0gZ2dwbG90KGRhdGEsIGFlcyh4ID0gLmRhdGFbW2xpZmVzdHlsZV92YXJdXSwgeSA9IHNldmVyaXR5X29mX2FueGlldHlfYXR0YWNrXzFfMTApKSArDQogICAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMykgKw0KICAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UpICsNCiAgICBsYWJzKHRpdGxlID0gcGFzdGUoIkFueGlldHkgU2V2ZXJpdHkgdnMuIiwgbGlmZXN0eWxlX3ZhciksDQogICAgICAgICB4ID0gbGlmZXN0eWxlX3ZhciwNCiAgICAgICAgIHkgPSAiU2V2ZXJpdHkgb2YgQW54aWV0eSBBdHRhY2sgKDEtMTApIikNCiAgaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgeyAjIE9ubHkgcHJpbnQgaWYgY2FwdHVyZV9hbGxfb3V0cHV0IGlzIFRSVUUNCiAgICAgICAgcHJpbnQocGxvdCkNCiAgICB9DQogIHJldHVybihwbG90KQ0KfQ0KDQpsaWZlc3R5bGVfdmFycyA8LSBjKCJzbGVlcF9ob3VycyIsICJwaHlzaWNhbF9hY3Rpdml0eV9ocnNfd2VlayIsICJjYWZmZWluZV9pbnRha2VfbWdfZGF5IiwgImFsY29ob2xfY29uc3VtcHRpb25fZHJpbmtzX3dlZWsiLCAiZGlldF9xdWFsaXR5XzFfMTAiKQ0KDQpsaWZlc3R5bGVfcGxvdHMgPC0gbGFwcGx5KGxpZmVzdHlsZV92YXJzLCBmdW5jdGlvbih2YXIpIHsNCiAgcGxvdF9saWZlc3R5bGVfdnNfc2V2ZXJpdHkoYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCwgdmFyKQ0KfSkNCg0KDQojIC0tLSBBZ2UgR3JvdXBzIHZzLiBBbnhpZXR5IFNldmVyaXR5ICh3aXRoaW4gaGlnaC1zdHJlc3MvaGlnaC1zZXZlcml0eSkgLS0tDQphbnhpZXR5X2RhdGFfcHJvY2Vzc2VkIDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lDQogIG11dGF0ZShhZ2VfZ3JvdXAgPSBjdXQoYWdlLCBicmVha3MgPSBjKDE4LCAzMCwgNDUsIDY1KSwgbGFiZWxzID0gYygiMTgtMjkiLCAiMzAtNDQiLCAiNDUtNjQiKSwgaW5jbHVkZS5sb3dlc3QgPSBUUlVFKSkNCg0KcGxvdF9hZ2Vfc2V2ZXJpdHkgPC0gZ2dwbG90KGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lIGZpbHRlcihoaWdoX3N0cmVzcyA9PSAxLCBoaWdoX3NldmVyaXR5ID09IDEpLCBhZXMoeCA9IGFnZV9ncm91cCwgeSA9IHNldmVyaXR5X29mX2FueGlldHlfYXR0YWNrXzFfMTApKSArDQogIGdlb21fYm94cGxvdCgpICsNCiAgbGFicyh0aXRsZSA9ICJBbnhpZXR5IFNldmVyaXR5IGJ5IEFnZSBHcm91cCAoSGlnaCBTdHJlc3MvU2V2ZXJpdHkpIiwNCiAgICAgICB4ID0gIkFnZSBHcm91cCIsDQogICAgICAgeSA9ICJTZXZlcml0eSBvZiBBbnhpZXR5IEF0dGFjayAoMS0xMCkiKQ0KcHJpbnQocGxvdF9hZ2Vfc2V2ZXJpdHkpDQojIC0tLSBIaXN0b2dyYW1zIG9mIEtleSBNZXRyaWNzLCBGYWNldGVkIGJ5IGhpZ2hfc3RyZXNzIGFuZCBoaWdoX3NldmVyaXR5IC0tLQ0KDQojIEhlYXJ0IFJhdGUNCnBsb3RfaHJfZmFjZXQgPC0gZ2dwbG90KGFueGlldHlfZGF0YV9wcm9jZXNzZWQsIGFlcyh4ID0gaGVhcnRfcmF0ZV9icG1fZHVyaW5nX2F0dGFjaykpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDMwKSArDQogIGZhY2V0X2dyaWQoaGlnaF9zdHJlc3MgfiBoaWdoX3NldmVyaXR5KSArDQogIGxhYnModGl0bGUgPSAiSGVhcnQgUmF0ZSBEaXN0cmlidXRpb24gYnkgU3RyZXNzIGFuZCBTZXZlcml0eSIsDQogICAgICAgeCA9ICJIZWFydCBSYXRlIChicG0pIiwNCiAgICAgICB5ID0gIkNvdW50IikNCnByaW50KHBsb3RfaHJfZmFjZXQpDQoNCiMgQnJlYXRoaW5nIFJhdGUNCnBsb3RfYnJfZmFjZXQgPC0gZ2dwbG90KGFueGlldHlfZGF0YV9wcm9jZXNzZWQsIGFlcyh4ID0gYnJlYXRoaW5nX3JhdGVfYnJlYXRoc19taW4pKSArDQogIGdlb21faGlzdG9ncmFtKGJpbnMgPSAzMCkgKw0KICBmYWNldF9ncmlkKGhpZ2hfc3RyZXNzIH4gaGlnaF9zZXZlcml0eSkgKw0KICBsYWJzKHRpdGxlID0gIkJyZWF0aGluZyBSYXRlIERpc3RyaWJ1dGlvbiBieSBTdHJlc3MgYW5kIFNldmVyaXR5IiwNCiAgICAgICB4ID0gIkJyZWF0aGluZyBSYXRlIChicmVhdGhzL21pbikiLA0KICAgICAgIHkgPSAiQ291bnQiKQ0KcHJpbnQocGxvdF9icl9mYWNldCkNCg0KIyAtLS0gU3RhY2tlZCBCYXIgUGxvdHMgZm9yIENhdGVnb3JpY2FsIFZhcmlhYmxlcyAoUXVlc3Rpb24gNikgLS0tDQpwbG90X2NhdGVnb3JpY2FsX2NvbXBhcmlzb24gPC0gZnVuY3Rpb24oZGF0YSwgdmFyX25hbWUpIHsNCiAgICBwbG90IDwtIGdncGxvdChkYXRhLCBhZXMoeCA9IGZhY3RvcihzZXZlcml0eV9vZl9hbnhpZXR5X2F0dGFja18xXzEwKSwgZmlsbCA9IC5kYXRhW1t2YXJfbmFtZV1dICkpICsNCiAgICAgICAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgICAgICAgbGFicyh0aXRsZSA9IHBhc3RlKCJQcm9wb3J0aW9uIG9mIiwgdmFyX25hbWUsICJieSBBbnhpZXR5IFNldmVyaXR5IiksDQogICAgICAgIHggPSAiU2V2ZXJpdHkgb2YgQW54aWV0eSBBdHRhY2sgKDEtMTApIiwNCiAgICAgICAgeSA9ICJQcm9wb3J0aW9uIiwNCiAgICAgICAgZmlsbCA9IHZhcl9uYW1lKSArDQogICAgICAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpDQogICAgaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgeyAjIE9ubHkgcHJpbnQgaWYgY2FwdHVyZV9hbGxfb3V0cHV0IGlzIFRSVUUNCiAgICAgICAgcHJpbnQocGxvdCkNCiAgICB9DQogICAgcmV0dXJuKHBsb3QpDQp9DQoNCmNhdGVnb3JpY2FsX3ZhcnNfcTYgPC0gYygic21va2luZyIsICJmYW1pbHlfaGlzdG9yeV9vZl9hbnhpZXR5IiwgImRpenppbmVzcyIsICJyZWNlbnRfbWFqb3JfbGlmZV9ldmVudCIpDQoNCmNhdGVnb3JpY2FsX2NvbXBhcmlzb25fcGxvdHMgPC0gbGFwcGx5KGNhdGVnb3JpY2FsX3ZhcnNfcTYsIGZ1bmN0aW9uKHZhcil7DQogICAgcGxvdF9jYXRlZ29yaWNhbF9jb21wYXJpc29uKGFueGlldHlfZGF0YV9wcm9jZXNzZWQsIHZhcikNCn0pDQoNCiMgQ29tYmluZSBhbmQgc2F2ZSBwbG90cw0KYWxsX3Bsb3RzIDwtIGMobGlzdChwbG90X3N0cmVzc19zZXZlcml0eSwgcGxvdF91bnRyZWF0ZWRfc2V2ZXJpdHkpLA0KICAgICAgICAgICAgICAgbGlmZXN0eWxlX3Bsb3RzLA0KICAgICAgICAgICAgICAgbGlzdChwbG90X2FnZV9zZXZlcml0eSwgcGxvdF9ocl9mYWNldCwgcGxvdF9icl9mYWNldCksDQogICAgICAgICAgICAgICBjYXRlZ29yaWNhbF9jb21wYXJpc29uX3Bsb3RzKQ0KDQpjb21iaW5lX2FuZF9zYXZlKGFsbF9wbG90cywgZmlsZS5wYXRoKHBsb3RzX2ZvbGRlciwgImNvbWJpbmVkX2FuYWx5c2lzX3Bsb3RzLnBuZyIpLCBuY29sID0gMywgdHlwZSA9ICJvdGhlciIpDQoNCg0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBwcmludChTeXMudGltZSgpKQ0KICBzaW5rKCkNCn0NCmBgYA0KDQojIyMgNi4zLiBDb3JyZWxhdGlvbiBBbmFseXNpcw0KDQpgYGB7ciBjb3JyZWxhdGlvbi1hbmFseXNpc30NCiMgLS0tIENvcnJlbGF0aW9uIEFuYWx5c2lzIC0tLQ0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBzaW5rKGZpbGUgPSBvdXRwdXRfZmlsZV9wYXRoLCBhcHBlbmQgPSBUUlVFLCBzcGxpdCA9IFRSVUUpDQogIGNhdCgiXG5cbi0tLSBDb3JyZWxhdGlvbiBBbmFseXNpcyAtLS1cblxuIikNCn0NCg0KIyBDYWxjdWxhdGUgY29ycmVsYXRpb25zDQpjb3JyZWxhdGlvbnMgPC0gYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCAlPiUNCiAgc2VsZWN0KGFsbF9vZihsaWZlc3R5bGVfdmFycyksIHNldmVyaXR5X29mX2FueGlldHlfYXR0YWNrXzFfMTApICU+JQ0KICBjb3IodXNlID0gInBhaXJ3aXNlLmNvbXBsZXRlLm9icyIpICAjIEhhbmRsZSBwb3RlbnRpYWwgbWlzc2luZyB2YWx1ZXMgKHRob3VnaCB3ZSBoYXZlIG5vbmUpDQoNCnByaW50KCJDb3JyZWxhdGlvbiBNYXRyaXg6IikNCnByaW50KGthYmxlKGNvcnJlbGF0aW9ucywgZm9ybWF0ID0gIm1hcmtkb3duIikpDQoNCiMgUGVyZm9ybSBjb3JyZWxhdGlvbiB0ZXN0cyAoZm9yIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSkNCmNvcnJlbGF0aW9uX3Rlc3RzIDwtIGxhcHBseShsaWZlc3R5bGVfdmFycywgZnVuY3Rpb24odmFyKSB7DQogIGNvci50ZXN0KGFueGlldHlfZGF0YV9wcm9jZXNzZWRbW3Zhcl1dLCBhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkJHNldmVyaXR5X29mX2FueGlldHlfYXR0YWNrXzFfMTApDQp9KQ0KbmFtZXMoY29ycmVsYXRpb25fdGVzdHMpIDwtIGxpZmVzdHlsZV92YXJzICMgTmFtZSB0aGUgbGlzdCBlbGVtZW50cw0KDQpwcmludCgiQ29ycmVsYXRpb24gVGVzdHM6IikNCiMgVXNpbmcgY2FwdHVyZS5vdXRwdXQgdG8gZm9ybWF0IHRoZSBjb3JyZWxhdGlvbiB0ZXN0IHJlc3VsdHMNCmZvciAodmFyIGluIG5hbWVzKGNvcnJlbGF0aW9uX3Rlc3RzKSkgew0KICAgIGNhdChwYXN0ZSgiXG4qKiogQ29ycmVsYXRpb24gVGVzdCBmb3I6IiwgdmFyLCAiKioqXG4iKSkNCiAgICBjYXQoY2FwdHVyZS5vdXRwdXQocHJpbnQoY29ycmVsYXRpb25fdGVzdHNbW3Zhcl1dKSksIHNlcCA9ICJcbiIpDQp9DQoNCg0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBwcmludChTeXMudGltZSgpKQ0KICBzaW5rKCkNCn0NCmBgYA0KDQojIyMgNi40LiBTdGF0aXN0aWNhbCBUZXN0cyAoT3B0aW9uYWwpDQoNCmBgYHtyIHN0YXRpc3RpY2FsLXRlc3RzfQ0KIyAtLS0gU3RhdGlzdGljYWwgVGVzdHMgLS0tDQoNCmlmIChjYXB0dXJlX2FsbF9vdXRwdXQpIHsNCiAgc2luayhmaWxlID0gb3V0cHV0X2ZpbGVfcGF0aCwgYXBwZW5kID0gVFJVRSwgc3BsaXQgPSBUUlVFKQ0KICBjYXQoIlxuXG4tLS0gU3RhdGlzdGljYWwgVGVzdHMgLS0tXG5cbiIpDQp9DQoNCiMgLS0tIFQtdGVzdDogSGVhcnQgUmF0ZSBieSBIaWdoIFNldmVyaXR5IC0tLQ0KIyBRdWVzdGlvbiA4DQp0X3Rlc3RfaHIgPC0gdC50ZXN0KGhlYXJ0X3JhdGVfYnBtX2R1cmluZ19hdHRhY2sgfiBoaWdoX3NldmVyaXR5LCBkYXRhID0gYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCkNCnByaW50KCJULXRlc3Q6IEhlYXJ0IFJhdGUgYnkgSGlnaCBTZXZlcml0eSIpDQpwcmludCh0X3Rlc3RfaHIpDQoNCg0KIyAtLS0gQ2hpLXNxdWFyZWQgVGVzdDogU21va2luZyBieSBIaWdoIFNldmVyaXR5IC0tLQ0KIyBRdWVzdGlvbiA2DQpjaGlzcV90ZXN0X3Ntb2tpbmcgPC0gY2hpc3EudGVzdChhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkJHNtb2tpbmcsIGFueGlldHlfZGF0YV9wcm9jZXNzZWQkaGlnaF9zZXZlcml0eSkNCnByaW50KCJDaGktc3F1YXJlZCBUZXN0OiBTbW9raW5nIGJ5IEhpZ2ggU2V2ZXJpdHkiKQ0KcHJpbnQoY2hpc3FfdGVzdF9zbW9raW5nKQ0KDQppZiAoY2FwdHVyZV9hbGxfb3V0cHV0KSB7DQogICAgcHJpbnQoU3lzLnRpbWUoKSkNCiAgICBzaW5rKCkNCn0NCmBgYA0KDQojIyMgNi41LiBNb2RlbGluZyAoT3B0aW9uYWwpDQoNCmBgYHtyIG1vZGVsaW5nfQ0KIyAtLS0gTG9naXN0aWMgUmVncmVzc2lvbiBNb2RlbCAoT3B0aW9uYWwpIC0tLQ0KDQppZiAoY2FwdHVyZV9hbGxfb3V0cHV0KSB7DQogIHNpbmsoZmlsZSA9IG91dHB1dF9maWxlX3BhdGgsIGFwcGVuZCA9IFRSVUUsIHNwbGl0ID0gVFJVRSkNCiAgY2F0KCJcblxuLS0tIExvZ2lzdGljIFJlZ3Jlc3Npb24gTW9kZWwgLS0tXG5cbiIpDQp9DQoNCiMgQnVpbGQgdGhlIG1vZGVsIChwcmVkaWN0aW5nIGhpZ2hfc2V2ZXJpdHkpDQptb2RlbCA8LSBnbG0oaGlnaF9zZXZlcml0eSB+IGFnZSArIGdlbmRlciArIHNsZWVwX2hvdXJzICsgcGh5c2ljYWxfYWN0aXZpdHlfaHJzX3dlZWsgKw0KICAgICAgICAgICAgICAgY2FmZmVpbmVfaW50YWtlX21nX2RheSArIGFsY29ob2xfY29uc3VtcHRpb25fZHJpbmtzX3dlZWsgKw0KICAgICAgICAgICAgICAgc21va2luZyArIGZhbWlseV9oaXN0b3J5X29mX2FueGlldHkgKyBzdHJlc3NfbGV2ZWxfMV8xMCArDQogICAgICAgICAgICAgICBkaXp6aW5lc3MgKyBtZWRpY2F0aW9uICsgdGhlcmFweV9zZXNzaW9uc19wZXJfbW9udGggKw0KICAgICAgICAgICAgICAgcmVjZW50X21ham9yX2xpZmVfZXZlbnQgKyBkaWV0X3F1YWxpdHlfMV8xMCArIGxvd19zbGVlcCArIGhpZ2hfYWxjb2hvbCArIGhpZ2hfY2FmZmVpbmUsDQogICAgICAgICAgICAgZGF0YSA9IGFueGlldHlfZGF0YV9wcm9jZXNzZWQsIGZhbWlseSA9ICJiaW5vbWlhbCIpDQoNCiMgU3VtbWFyaXplIHRoZSBtb2RlbA0Kc3VtbWFyeShtb2RlbCkNCg0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICAgIHByaW50KFN5cy50aW1lKCkpDQogICAgc2luaygpDQp9DQpgYGANCg0KIyMjIDYuNiBFbmhhbmNlbWVudHMNCg0KYGBge3IgYW5hbHl6ZS1lbmhhbmNlbWVudHN9DQojIC0tLSBFbmhhbmNlbWVudHMgdG8gQW5hbHl6ZSBQaGFzZSAtLS0NCg0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICBzaW5rKGZpbGUgPSBvdXRwdXRfZmlsZV9wYXRoLCBhcHBlbmQgPSBUUlVFLCBzcGxpdCA9IFRSVUUpDQogIGNhdCgiXG5cbi0tLSBBbmFseXplIFBoYXNlIEVuaGFuY2VtZW50cyAtLS1cblxuIikNCn0NCg0KIyAtLS0gUXVlc3Rpb24gMjogQ29tcGFyZSBMaWZlc3R5bGUgRmFjdG9ycyB0byBPdmVyYWxsIEF2ZXJhZ2VzIC0tLQ0KY2F0KCJcblF1ZXN0aW9uIDI6IExpZmVzdHlsZSBGYWN0b3IgQ29tcGFyaXNvbnMgKEhpZ2ggU3RyZXNzL1NldmVyaXR5IHZzLiBPdmVyYWxsKTpcbiIpDQoNCiMgQ2FsY3VsYXRlIG92ZXJhbGwgYXZlcmFnZXMNCm92ZXJhbGxfbWVhbnMgPC0gYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCAlPiUNCiAgc3VtbWFyaXplKGFjcm9zcyhhbGxfb2YobGlmZXN0eWxlX3ZhcnMpLCB+IG1lYW4oLngsIG5hLnJtID0gVFJVRSkpKQ0KDQojIENhbGN1bGF0ZSBhdmVyYWdlcyBmb3IgaGlnaC1zdHJlc3MvaGlnaC1zZXZlcml0eSBncm91cA0KaGlnaF9zdHJlc3Nfc2V2ZXJpdHlfbWVhbnMgPC0gYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCAlPiUNCiAgZmlsdGVyKGhpZ2hfc3RyZXNzID09IDEsIGhpZ2hfc2V2ZXJpdHkgPT0gMSkgJT4lDQogIHN1bW1hcml6ZShhY3Jvc3MoYWxsX29mKGxpZmVzdHlsZV92YXJzKSwgfiBtZWFuKC54LCBuYS5ybSA9IFRSVUUpKSkNCg0KIyBDb21iaW5lIGFuZCBwcmludC4gIFVzZSBrYWJsZSBmb3IgbmljZSBmb3JtYXR0aW5nLg0KY29tcGFyaXNvbl90YWJsZSA8LSBiaW5kX3Jvd3MoDQogICJPdmVyYWxsIiA9IG92ZXJhbGxfbWVhbnMsDQogICJIaWdoIFN0cmVzcy9TZXZlcml0eSIgPSBoaWdoX3N0cmVzc19zZXZlcml0eV9tZWFucywNCiAgLmlkID0gIkdyb3VwIg0KKQ0KcHJpbnQoa2FibGUoY29tcGFyaXNvbl90YWJsZSwgZm9ybWF0ID0gIm1hcmtkb3duIikpDQoNCg0KIyAtLS0gUXVlc3Rpb24gNDogQWdlIEdyb3VwIEFuYWx5c2lzIHdpdGhpbiBIaWdoIFN0cmVzcy9TZXZlcml0eSAtLS0NCmNhdCgiXG5RdWVzdGlvbiA0OiBBZ2UgR3JvdXAgQW5hbHlzaXMgd2l0aGluIEhpZ2ggU3RyZXNzL1NldmVyaXR5OlxuIikNCg0KIyBMaWZlc3R5bGUgZmFjdG9ycyBieSBhZ2UgZ3JvdXANCmxpZmVzdHlsZV9ieV9hZ2UgPC0gYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCAlPiUNCiAgZmlsdGVyKGhpZ2hfc3RyZXNzID09IDEsIGhpZ2hfc2V2ZXJpdHkgPT0gMSkgJT4lDQogIGdyb3VwX2J5KGFnZV9ncm91cCkgJT4lDQogIHN1bW1hcml6ZShhY3Jvc3MoYWxsX29mKGxpZmVzdHlsZV92YXJzKSwgfiBtZWFuKC54LCBuYS5ybSA9IFRSVUUpKSkNCnByaW50KGthYmxlKGxpZmVzdHlsZV9ieV9hZ2UsIGZvcm1hdCA9ICJtYXJrZG93biIpKQ0KDQoNCiMgVHJlYXRtZW50IHVzYWdlIGJ5IGFnZSBncm91cA0KdHJlYXRtZW50X2J5X2FnZSA8LSBhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkICU+JQ0KICBmaWx0ZXIoaGlnaF9zdHJlc3MgPT0gMSwgaGlnaF9zZXZlcml0eSA9PSAxKSAlPiUNCiAgZ3JvdXBfYnkoYWdlX2dyb3VwKSAlPiUNCiAgc3VtbWFyaXplKHBlcmNlbnRfdGhlcmFweSA9IG1lYW4odGhlcmFweV9zZXNzaW9uc19wZXJfbW9udGggPiAwKSAqIDEwMCwNCiAgICAgICAgICAgIHBlcmNlbnRfbWVkaWNhdGlvbiA9IG1lYW4obWVkaWNhdGlvbiA9PSAiWWVzIikgKiAxMDApDQpwcmludChrYWJsZSh0cmVhdG1lbnRfYnlfYWdlLCBmb3JtYXQgPSAibWFya2Rvd24iKSkNCg0KDQojIC0tLSBRdWVzdGlvbiA2OiBIaWdoIHZzLiBMb3cgU2V2ZXJpdHkgQ29tcGFyaXNvbnMgLS0tDQpjYXQoIlxuUXVlc3Rpb24gNjogSGlnaCB2cy4gTG93IFNldmVyaXR5IENvbXBhcmlzb25zOlxuIikNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbnMgZm9yIGhpZ2ggc2V2ZXJpdHkNCmhpZ2hfc2V2ZXJpdHlfcHJvcHMgPC0gYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCAlPiUNCiAgZmlsdGVyKGhpZ2hfc2V2ZXJpdHkgPT0gMSkgJT4lDQogIHN1bW1hcml6ZShhY3Jvc3MoYWxsX29mKGNhdGVnb3JpY2FsX3ZhcnNfcTYpLCB+IG1lYW4oLnggPT0gIlllcyIpICogMTAwKSkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbnMgZm9yIGxvdyBzZXZlcml0eQ0KbG93X3NldmVyaXR5X3Byb3BzIDwtIGFueGlldHlfZGF0YV9wcm9jZXNzZWQgJT4lDQogIGZpbHRlcihzZXZlcml0eV9vZl9hbnhpZXR5X2F0dGFja18xXzEwIDwgNCkgJT4lDQogIHN1bW1hcml6ZShhY3Jvc3MoYWxsX29mKGNhdGVnb3JpY2FsX3ZhcnNfcTYpLCB+IG1lYW4oLnggPT0gIlllcyIpICogMTAwKSkNCg0KIyBDb21iaW5lIGFuZCBwcmludA0KY29tcGFyaXNvbl90YWJsZV9xNiA8LSBiaW5kX3Jvd3MoDQogICJIaWdoIFNldmVyaXR5IiA9IGhpZ2hfc2V2ZXJpdHlfcHJvcHMsDQogICJMb3cgU2V2ZXJpdHkiID0gbG93X3NldmVyaXR5X3Byb3BzLA0KICAuaWQgPSAiR3JvdXAiDQopDQpwcmludChrYWJsZShjb21wYXJpc29uX3RhYmxlX3E2LCBmb3JtYXQgPSAibWFya2Rvd24iKSkNCg0KIyBDaGktc3F1YXJlZCB0ZXN0cyBmb3IgZWFjaCB2YXJpYWJsZSwgY2FwdHVyaW5nIG91dHB1dA0KZm9yICh2YXIgaW4gY2F0ZWdvcmljYWxfdmFyc19xNikgew0KICAgIGNhdChwYXN0ZSgiXG5DaGktc3F1YXJlZCB0ZXN0IGZvciIsIHZhciwgIjpcbiIpKQ0KICAgIHRibCA8LSB0YWJsZShhbnhpZXR5X2RhdGFfcHJvY2Vzc2VkW1t2YXJdXSwgYW54aWV0eV9kYXRhX3Byb2Nlc3NlZCRoaWdoX3NldmVyaXR5KQ0KICAgIHByaW50KGNhcHR1cmUub3V0cHV0KGNoaXNxLnRlc3QodGJsKSkpDQp9DQoNCmlmIChjYXB0dXJlX2FsbF9vdXRwdXQpIHsNCiAgcHJpbnQoU3lzLnRpbWUoKSkNCiAgc2luaygpDQp9DQpgYGANCg0KIyMjIDYuNyBBbmFseXNpcyBTdW1tYXJ5IGFuZCBGaW5kaW5ncw0KDQpBZGQgYSBzZWN0aW9uIHRvIHN1bW1hcml6ZSBhbGwgdGhlIGZpbmRpbmdzIGZyb20gdGhlIGRpZmZlcmVudCBhbmFseXNpcyBhbmQgdGllIGl0IHdpdGggdGhlIHF1ZXN0aW9ucyBkZWZpbmVkIGluIHRoZSBBc2sgcGhhc2UuDQoNCmBgYHtyIGFuYWx5c2lzLXN1bW1hcnl9DQojIC0tLSBBbmFseXNpcyBTdW1tYXJ5IGFuZCBGaW5kaW5ncyAtLS0NCmlmIChjYXB0dXJlX2FsbF9vdXRwdXQpIHsNCiAgc2luayhmaWxlID0gb3V0cHV0X2ZpbGVfcGF0aCwgYXBwZW5kID0gVFJVRSwgc3BsaXQgPSBUUlVFKQ0KICBjYXQoIlxuXG4tLS0gQW5hbHlzaXMgU3VtbWFyeSBhbmQgRmluZGluZ3MgLS0tXG5cbiIpDQp9DQojVG8gYmUgYWRkZWQgaW4gdGhlIG5leHQgc3RlcA0KaWYgKGNhcHR1cmVfYWxsX291dHB1dCkgew0KICAgIHByaW50KFN5cy50aW1lKCkpDQogICAgc2luaygpDQp9DQpgYGANCg0KYGBge3IgY2xvc2Utc2luaywgaW5jbHVkZT1GQUxTRSwgZXZhbD1jYXB0dXJlX2FsbF9vdXRwdXR9DQojIEVuc3VyZSBzaW5rIGlzIGNsb3NlZCBldmVuIGlmIHRoZXJlJ3MgYW4gZXJyb3IgaW4gYSBwcmV2aW91cyBjaHVuaw0KaWYgKHNpbmsubnVtYmVyKCkgPiAwKSB7DQogICAgcHJpbnQoU3lzLnRpbWUoKSkNCiAgc2luaygpDQp9DQpgYGANCg0KDQo=